AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet.
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
int32 GetCastTimeRemaining ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Unitm_reflectionTarget
 
ObjectGuid m_reflectionTargetGuid
 
Position m_reflectionTargetPosition
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
570 :
571 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
572 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
574{
576 m_skipCheck = skipCheck;
577 m_selfContainer = nullptr;
579 m_executedCurrently = false;
582 m_comboTarget = nullptr;
583 m_delayStart = 0;
585
587 m_auraScaleMask = 0;
588 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
589
590 // Get data for type of attack
591 switch (m_spellInfo->DmgClass)
592 {
596 else
598 break;
601 break;
602 default:
603 // Wands
606 else
608 break;
609 }
610
611 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
612
614 // wand case
617 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
618
619 if (originalCasterGUID)
620 m_originalCasterGUID = originalCasterGUID;
621 else
623
626 else
627 {
630 m_originalCaster = nullptr;
631 }
632
634 _triggeredCastFlags = triggerFlags;
635 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
637
638 m_CastItem = nullptr;
639
640 unitTarget = nullptr;
641 itemTarget = nullptr;
642 gameObjTarget = nullptr;
643 destTarget = nullptr;
644 damage = 0;
645 m_reflectionTarget = nullptr;
650 m_damage = 0;
651 m_healing = 0;
652 m_procAttacker = 0;
653 m_procVictim = 0;
654 m_procEx = 0;
655 focusObject = nullptr;
656 m_cast_count = 0;
657 m_glyphIndex = 0;
658 m_preCastSpell = 0;
659 m_spellAura = nullptr;
660 _scriptsLoaded = false;
661
662 //Auto Shot & Shoot (wand)
664
665 m_runesState = 0;
666 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
667 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
668 m_timer = 0; // will set to castime in prepare
669 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
670 m_immediateHandled = false;
671
673
675
676 // Determine if spell can be reflected back to the caster
677 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
681
683 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
684
685 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
687
688 // xinef:
689 _spellTargetsSelected = false;
690
691 m_weaponItem = nullptr;
692}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1637
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ DIMINISHING_NONE
Definition SharedDefines.h:3498
@ SPELL_EFFECT_DISPEL
Definition SharedDefines.h:827
#define CLASSMASK_WAND_USERS
Definition SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition SharedDefines.h:472
@ SPELL_ATTR1_NO_REFLECTION
Definition SharedDefines.h:437
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition SharedDefines.h:528
@ SPELL_DAMAGE_CLASS_RANGED
Definition SharedDefines.h:1559
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1557
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1558
@ SPELL_CUSTOM_ERROR_NONE
Definition SharedDefines.h:1154
@ SPELL_ATTR0_IS_ABILITY
Definition SharedDefines.h:397
@ SPELL_ATTR0_NO_IMMUNITIES
Definition SharedDefines.h:422
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition SharedDefines.h:548
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition SharedDefines.h:633
SpellSchoolMask
Definition SharedDefines.h:306
TriggerCastFlags
Definition SpellDefines.h:132
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition SpellDefines.h:141
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition SpellDefines.h:139
#define sSpellMgr
Definition SpellMgr.h:826
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:244
@ SPELL_FLAG_NORMAL
Definition Spell.h:84
@ SPELL_STATE_NULL
Definition Spell.h:234
@ OFF_ATTACK
Definition Unit.h:217
@ BASE_ATTACK
Definition Unit.h:216
@ RANGED_ATTACK
Definition Unit.h:218
@ DIMINISHING_LEVEL_1
Definition Unit.h:270
Definition ByteBuffer.h:70
Definition Item.h:220
void Clear()
Definition ObjectGuid.h:138
bool IsPlayer() const
Definition Object.h:200
Player * ToPlayer()
Definition Object.h:201
bool IsInWorld() const
Definition Object.h:108
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition PlayerStorage.cpp:490
bool IsPassive() const
Definition SpellInfo.cpp:1098
bool NeedsComboPoints() const
Definition SpellInfo.cpp:1266
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition SpellInfo.cpp:876
bool IsPositive() const
Definition SpellInfo.cpp:1237
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1283
uint32 DmgClass
Definition SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition SpellInfo.cpp:1276
Unit * m_comboTarget
Definition Spell.h:553
int8 m_comboPointGain
Definition Spell.h:554
GameObject * gameObjTarget
Definition Spell.h:665
bool m_referencedFromCurrentSpell
Definition Spell.h:656
bool m_canReflect
Definition Spell.h:632
uint32 m_procVictim
Definition Spell.h:690
Unit * m_originalCaster
Definition Spell.h:620
bool m_needComboPoints
Definition Spell.h:658
uint64 m_delayStart
Definition Spell.h:650
bool _scriptsLoaded
Definition Spell.h:741
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:782
int32 damage
Definition Spell.h:667
SpellEffectHandleMode effectHandleMode
Definition Spell.h:668
int32 m_channeledDuration
Definition Spell.h:631
Aura * m_spellAura
Definition Spell.h:673
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:716
Unit *const m_caster
Definition Spell.h:614
uint8 m_delayAtDamageCount
Definition Spell.h:639
WeaponAttackType m_attackType
Definition Spell.h:628
bool m_immediateHandled
Definition Spell.h:653
uint32 m_spellState
Definition Spell.h:778
ObjectGuid m_originalCasterGUID
Definition Spell.h:618
void CleanupTargetList()
Definition Spell.cpp:2275
int32 m_timer
Definition Spell.h:779
int32 m_casttime
Definition Spell.h:630
Item * itemTarget
Definition Spell.h:664
uint8 m_cast_count
Definition Spell.h:535
int32 m_damage
Definition Spell.h:683
bool m_executedCurrently
Definition Spell.h:657
DiminishingLevels m_diminishLevel
Definition Spell.h:676
float m_damageMultipliers[3]
Definition Spell.h:660
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:796
uint8 m_auraScaleMask
Definition Spell.h:790
SpellCustomErrors m_customError
Definition Spell.h:539
uint8 m_spellFlags
Definition Spell.h:634
bool m_skipCheck
Definition Spell.h:789
int32 m_healing
Definition Spell.h:684
uint32 m_glyphIndex
Definition Spell.h:536
uint8 m_channelTargetEffectMask
Definition Spell.h:698
Item * m_weaponItem
Definition Spell.h:533
Unit * unitTarget
Definition Spell.h:663
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:627
Unit * m_reflectionTarget
Definition Spell.h:669
SpellEvent * _spellEvent
Definition Spell.h:781
bool _spellTargetsSelected
Definition Spell.h:794
ObjectGuid m_reflectionTargetGuid
Definition Spell.h:670
uint32 m_preCastSpell
Definition Spell.h:537
WorldLocation * destTarget
Definition Spell.h:666
Spell ** m_selfContainer
Definition Spell.h:622
uint8 m_applyMultiplierMask
Definition Spell.h:659
DiminishingGroup m_diminishGroup
Definition Spell.h:677
uint32 m_procEx
Definition Spell.h:691
Item * m_CastItem
Definition Spell.h:532
SpellValue *const m_spellValue
Definition Spell.h:616
int32 m_powerCost
Definition Spell.h:629
uint32 m_procAttacker
Definition Spell.h:689
GameObject * focusObject
Definition Spell.h:680
SpellInfo const *const m_spellInfo
Definition Spell.h:531
uint8 m_runesState
Definition Spell.h:637
bool m_autoRepeat
Definition Spell.h:636
Unit * GetCharmerOrOwner() const
Definition Unit.h:1271
uint32 getClassMask() const
Definition Unit.h:835
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:199
Definition Spell.h:104
Definition Spell.h:221

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), ObjectGuid::Clear(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_reflectionTarget, m_reflectionTargetGuid, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

Referenced by Creature::HasSpellFocus().

◆ ~Spell()

Spell::~Spell ( )
695{
696 // unload scripts
697 while (!m_loadedScripts.empty())
698 {
699 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
700 (*itr)->_Unload();
701 delete (*itr);
702 m_loadedScripts.erase(itr);
703 }
704
706 {
707 // Clean the reference to avoid later crash.
708 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
709 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
710 *m_selfContainer = nullptr;
711 }
712
713 delete m_spellValue;
714
716}
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
uint32 Id
Definition SpellInfo.h:320
void CheckEffectExecuteData()
Definition Spell.cpp:8493
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:756

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3738{
3739 // update pointers base at GUIDs to prevent access to non-existed already object
3740 if (!UpdatePointers())
3741 {
3742 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3743 cancel();
3744 return;
3745 }
3746
3747 // cancel at lost explicit target during cast
3749 {
3750 cancel();
3751 return;
3752 }
3753
3754 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3756 {
3758 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3760
3761 if (Unit* charm = m_caster->GetCharm())
3762 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3763 }
3764
3765 if (Player* playerCaster = m_caster->ToPlayer())
3766 {
3767 // now that we've done the basic check, now run the scripts
3768 // should be done before the spell is actually executed
3769 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3770
3771 // As of 3.0.2 pets begin attacking their owner's target immediately
3772 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3773 // This prevents spells such as Hunter's Mark from triggering pet attack
3774 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3776 if (!playerCaster->m_Controlled.empty())
3777 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3778 if (Unit* pet = *itr)
3779 if (pet->IsAlive() && pet->IsCreature())
3780 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3781 }
3782
3784
3788
3790
3791 Player* modOwner = m_caster->GetSpellModOwner();
3792 // skip check if done already (for instant cast spells for example)
3793 if (!skipCheck)
3794 {
3795 SpellCastResult castResult = CheckCast(false);
3796 if (castResult != SPELL_CAST_OK)
3797 {
3798 SendCastResult(castResult);
3799 SendInterrupted(0);
3800
3801 finish(false);
3802 SetExecutedCurrently(false);
3803 return;
3804 }
3805
3806 // additional check after cast bar completes (must not be in CheckCast)
3807 // if trade not complete then remember it in trade data
3809 {
3810 if (m_caster->IsPlayer())
3811 {
3812 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3813 {
3814 if (!my_trade->IsInAcceptProcess())
3815 {
3816 // Spell will be casted at completing the trade. Silently ignore at this place
3817 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3819 SendInterrupted(0);
3820
3821 finish(false);
3822 SetExecutedCurrently(false);
3823 return;
3824 }
3825 }
3826 }
3827 }
3828 }
3829
3830 if (modOwner)
3831 modOwner->SetSpellModTakingSpell(this, true);
3832
3835
3836 if (modOwner)
3837 modOwner->SetSpellModTakingSpell(this, false);
3838
3839 // Spell may be finished after target map check
3841 {
3842 SendInterrupted(0);
3843 finish(false);
3844 SetExecutedCurrently(false);
3845 return;
3846 }
3847
3848 if (modOwner)
3849 modOwner->SetSpellModTakingSpell(this, true);
3850
3852
3854
3855 if (modOwner)
3856 modOwner->SetSpellModTakingSpell(this, false);
3857
3858 // traded items have trade slot instead of guid in m_itemTargetGUID
3859 // set to real guid to be sent later to the client
3861
3862 if (m_caster->IsPlayer())
3863 {
3865 {
3868 }
3869
3871 }
3872
3874 {
3875 // Powers have to be taken before SendSpellGo
3876 TakePower();
3877 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3878 }
3879 else if (Item* targetItem = m_targets.GetItemTarget())
3880 {
3882 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3883 TakeReagents();
3884 }
3885
3887
3888 // CAST SPELL
3889 if (modOwner)
3890 modOwner->SetSpellModTakingSpell(this, true);
3891
3893
3895
3896 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3897 SendSpellGo();
3898
3899 if (modOwner)
3900 modOwner->SetSpellModTakingSpell(this, false);
3901
3902 if (m_originalCaster)
3903 {
3904 // Handle procs on cast
3905 uint32 procAttacker = m_procAttacker;
3906 if (!procAttacker)
3907 {
3908 bool IsPositive = m_spellInfo->IsPositive();
3910 {
3912 }
3913 else
3914 {
3916 }
3917 }
3918
3919 uint32 procEx = PROC_EX_NORMAL_HIT;
3920
3921 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3922 {
3923 if (ihit->missCondition != SPELL_MISS_NONE)
3924 {
3925 continue;
3926 }
3927
3928 if (!ihit->crit)
3929 {
3930 continue;
3931 }
3932
3933 procEx |= PROC_EX_CRITICAL_HIT;
3934 break;
3935 }
3936
3939 }
3940
3941 if (modOwner)
3942 modOwner->SetSpellModTakingSpell(this, true);
3943
3945 if (resetAttackTimers)
3946 {
3948 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3949 {
3950 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3951 {
3952 resetAttackTimers = false;
3953 break;
3954 }
3955 }
3956 }
3957
3958 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
3959 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
3960 {
3961 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
3962 // in case delayed spell remove item at cast delay start
3963 TakeCastItem();
3964
3965 // Okay, maps created, now prepare flags
3966 m_immediateHandled = false;
3968 SetDelayStart(0);
3969
3972
3973 // remove all applied mods at this point
3974 // dont allow user to use them twice in case spell did not reach current target
3975 if (modOwner)
3976 modOwner->RemoveSpellMods(this);
3977
3978 // Xinef: why do we keep focus after spell is sent to air?
3979 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
3980 // Xinef: we get focused to it out of nowhere...
3981 if (Creature* creatureCaster = m_caster->ToCreature())
3982 creatureCaster->ReleaseFocus(this);
3983 }
3984 else
3985 {
3986 // Immediate spell, no big deal
3988 }
3989
3990 if (resetAttackTimers)
3991 {
3992 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
3993 {
3994 resetAttackTimers = false;
3995 }
3996
3997 if (resetAttackTimers)
3998 {
4000
4002 {
4004 }
4005
4007 }
4008 }
4009
4011
4012 if (modOwner)
4013 modOwner->SetSpellModTakingSpell(this, false);
4014
4015 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4016 {
4017 for (int32 id : *spell_triggered)
4018 {
4019 if (id < 0)
4021 else
4023 }
4024 }
4025
4026 // Interrupt Spell casting
4027 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4029 if (Unit* target = m_targets.GetUnitTarget())
4030 if (target->IsCreature())
4031 m_caster->CastSpell(target, 32747, true);
4032
4033 // xinef: start combat at cast for delayed spells, only for explicit target
4034 if (Unit* target = m_targets.GetUnitTarget())
4037 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4038
4039 if (m_caster->IsPlayer())
4042
4043 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4044
4045 SetExecutedCurrently(false);
4046
4047 // Call CreatureAI hook OnSpellCastFinished
4048 if (m_originalCaster)
4049 if (Creature* caster = m_originalCaster->ToCreature())
4050 if (caster->IsAIEnabled)
4051 caster->AI()->OnSpellCastFinished(GetSpellInfo(), SPELL_FINISHED_SUCCESSFUL_CAST);
4052}
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:143
std::int32_t int32
Definition Define.h:103
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
@ CHEAT_COOLDOWN
Definition Player.h:998
#define sScriptMgr
Definition ScriptMgr.h:725
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition SharedDefines.h:663
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:845
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition SharedDefines.h:484
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition SharedDefines.h:430
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition SharedDefines.h:521
@ SPELL_DAMAGE_CLASS_NONE
Definition SharedDefines.h:1556
@ SPELL_MISS_NONE
Definition SharedDefines.h:1530
SpellCastResult
Definition SharedDefines.h:959
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:987
@ SPELL_CAST_OK
Definition SharedDefines.h:1149
@ SPELL_AURA_MOD_CHARM
Definition SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition SpellAuraDefines.h:64
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition SpellDefines.h:136
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition SpellDefines.h:137
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition SpellDefines.h:143
@ TARGET_FLAG_TRADE_ITEM
Definition SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition SpellInfo.h:47
@ PROC_EX_CRITICAL_HIT
Definition SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:125
@ PROC_FLAG_NONE
Definition SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:131
@ SPELL_FINISHED_SUCCESSFUL_CAST
Definition Spell.h:98
@ SPELL_STATE_DELAYED
Definition Spell.h:239
@ SPELL_STATE_FINISHED
Definition Spell.h:237
@ UNIT_STATE_CASTING
Definition UnitDefines.h:185
Definition Creature.h:47
uint32 GetEntry() const
Definition Object.h:116
bool IsCreature() const
Definition Object.h:204
Creature * ToCreature()
Definition Object.h:205
Definition Pet.h:41
Definition Player.h:1085
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2166
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10054
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:13947
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:9976
Pet * GetPet() const
Definition Player.cpp:8947
bool GetCommandStatus(uint32 command) const
Definition Player.h:1198
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9097
TradeData * GetTradeData() const
Definition Player.h:1394
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3521
WorldObject * GetObjectTarget() const
Definition Spell.cpp:310
void UpdateTradeSlotItem()
Definition Spell.cpp:347
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:315
Item * GetItemTarget() const
Definition Spell.h:149
uint32 GetTargetMask() const
Definition Spell.h:127
Unit * GetUnitTarget() const
Definition Spell.cpp:231
float Speed
Definition SpellInfo.h:370
bool IsChanneled() const
Definition SpellInfo.cpp:1256
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2246
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:893
SpellInfo const * GetSpellInfo() const
Definition Spell.h:587
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8547
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8753
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:565
SpellCastTargets m_targets
Definition Spell.h:538
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:787
void handle_immediate()
Definition Spell.cpp:4054
void SendSpellGo()
Definition Spell.cpp:4746
void TakeReagents()
Definition Spell.cpp:5481
void SetExecutedCurrently(bool yes)
Definition Spell.h:573
void SendInterrupted(uint8 result)
Definition Spell.cpp:5123
void PrepareScriptHitHandlers()
Definition Spell.cpp:8579
void CallScriptOnCastHandlers()
Definition Spell.cpp:8534
void cancel(bool bySelf=false)
Definition Spell.cpp:3647
void SendSpellCooldown()
Definition Spell.cpp:4294
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8521
void HandleLaunchPhase()
Definition Spell.cpp:8224
bool UpdatePointers()
Definition Spell.cpp:7854
void SetDelayStart(uint64 m_time)
Definition Spell.h:575
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:697
void SelectSpellTargets()
Definition Spell.cpp:820
void TakePower()
Definition Spell.cpp:5264
SpellCastResult CheckCast(bool strict)
Definition Spell.cpp:5603
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4618
uint64 GetDelayMoment() const
Definition Spell.h:576
void TakeCastItem()
Definition Spell.cpp:5201
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8068
void finish(bool ok=true)
Definition Spell.cpp:4426
Definition TradeData.h:36
Definition Unit.h:655
bool HasOffhandWeaponForAttack() const
Definition Unit.h:975
void ClearUnitState(uint32 f)
Definition Unit.h:727
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1413
Unit * GetCharm() const
Definition Unit.cpp:10881
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:671
Player * GetSpellModOwner() const
Definition Unit.cpp:16803
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition Unit.cpp:13866
bool IsPet() const
Definition Unit.h:787
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4146
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1194
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5028
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition Unit.cpp:6611
bool HasUnitState(const uint32 f) const
Definition Unit.h:726
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:10426
bool IsControlledByPlayer() const
Definition Unit.h:1292
void SetInFront(WorldObject const *target)
Definition Unit.cpp:20501
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:643
int8 effectIndex
Definition Spell.h:290
SpellInfo const * spellInfo
Definition Spell.h:289

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_FINISHED_SUCCESSFUL_CAST, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4220{
4221 // Take for real after all targets are processed
4223 {
4225 }
4226
4227 // Real add combo points from effects
4229 {
4230 // remove Premed-like effects unless they were caused by ourselves
4231 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4233 {
4235 }
4236
4238 }
4239
4241 {
4243 }
4244
4247 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4248 {
4249 // Xinef: Properly clear infinite cooldowns in some cases
4250 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4253 }
4254
4255 // Handle procs on finish
4256 if (m_originalCaster)
4257 {
4258 uint32 procAttacker = m_procAttacker;
4259 if (!procAttacker)
4260 {
4261 bool IsPositive = m_spellInfo->IsPositive();
4263 {
4265 }
4266 else
4267 {
4269 }
4270 }
4271
4272 uint32 procEx = PROC_EX_NORMAL_HIT;
4273 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4274 {
4275 if (ihit->missCondition != SPELL_MISS_NONE)
4276 {
4277 continue;
4278 }
4279
4280 if (!ihit->crit)
4281 {
4282 continue;
4283 }
4284
4285 procEx |= PROC_EX_CRITICAL_HIT;
4286 break;
4287 }
4288
4291 }
4292}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition SharedDefines.h:808
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition SpellMgr.h:245
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition Player.cpp:11074
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1212
bool IsAutoRepeat() const
Definition Spell.h:559
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8058
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:994
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:10826
void ClearComboPoints()
Definition Unit.cpp:17105
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:17079
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5236

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4192{
4193 m_spellAura = nullptr;
4194 // initialize Diminishing Returns Data
4197
4198 // handle some immediate features of the spell here
4200
4202
4203 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4204 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4205 {
4206 // don't do anything for empty effect
4207 if (!m_spellInfo->Effects[j].IsEffect())
4208 continue;
4209
4210 // call effect handlers to handle destination hit
4211 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4212 }
4213
4214 // process items
4215 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4216 DoAllEffectOnTarget(&(*ihit));
4217}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:246
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:393
void HandleThreatSpells()
Definition Spell.cpp:5530
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5577
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:714
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2513

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
542 {
543 if (target != m_comboTarget)
544 {
545 m_comboTarget = target;
546 m_comboPointGain = amount;
547 }
548 else
549 {
550 m_comboPointGain += amount;
551 }
552 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2509{
2510 m_destTargets[effIndex] = dest;
2511}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2418{
2419 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2420 {
2421 if (!m_spellInfo->Effects[effIndex].IsEffect())
2422 effectMask &= ~(1 << effIndex);
2423 else
2424 {
2425 switch (m_spellInfo->Effects[effIndex].Effect)
2426 {
2430 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2431 effectMask &= ~(1 << effIndex);
2432 break;
2433 default:
2434 break;
2435 }
2436 }
2437 }
2438
2439 if (!effectMask)
2440 return;
2441
2442 ObjectGuid targetGUID = go->GetGUID();
2443
2444 // Lookup target in already in list
2445 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2446 {
2447 if (targetGUID == ihit->targetGUID) // Found in list
2448 {
2449 ihit->effectMask |= effectMask; // Add only effect mask
2450 return;
2451 }
2452 }
2453
2454 // This is new target calculate data for him
2455
2456 GOTargetInfo target;
2457 target.targetGUID = targetGUID;
2458 target.effectMask = effectMask;
2459 target.processed = false; // Effects not apply on target
2460
2461 // Spell have speed - need calculate incoming time
2462 if (m_spellInfo->Speed > 0.0f)
2463 {
2464 // calculate spell incoming interval
2465 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2466 if (dist < 5.0f)
2467 dist = 5.0f;
2468 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2469 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2470 m_delayMoment = target.timeDelay;
2471 }
2472 else
2473 target.timeDelay = 0LL;
2474
2475 // Add target to list
2476 m_UniqueGOTargetInfo.push_back(target);
2477}
std::uint64_t uint64
Definition Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition SharedDefines.h:1604
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition SharedDefines.h:877
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition SharedDefines.h:878
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition SharedDefines.h:876
Definition ObjectGuid.h:118
uint64 m_delayMoment
Definition Spell.h:651
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:707
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1271

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2480{
2481 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2482 if (!m_spellInfo->Effects[effIndex].IsEffect())
2483 effectMask &= ~(1 << effIndex);
2484
2485 // no effects left
2486 if (!effectMask)
2487 return;
2488
2489 // Lookup target in already in list
2490 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2491 {
2492 if (item == ihit->item) // Found in list
2493 {
2494 ihit->effectMask |= effectMask; // Add only effect mask
2495 return;
2496 }
2497 }
2498
2499 // This is new target add data
2500
2501 ItemTargetInfo target;
2502 target.item = item;
2503 target.effectMask = effectMask;
2504
2505 m_UniqueItemInfo.push_back(target);
2506}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2285{
2286 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2287 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2288 effectMask &= ~(1 << effIndex);
2289
2290 // no effects left
2291 if (!effectMask)
2292 return;
2293
2294 if (checkIfValid)
2295 {
2296 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2297 if (res != SPELL_CAST_OK)
2298 return;
2299 }
2300
2301 // Check for effect immune skip if immuned
2302 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2303 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2304 effectMask &= ~(1 << effIndex);
2305
2306 ObjectGuid targetGUID = target->GetGUID();
2307
2308 // Lookup target in already in list
2309 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2310 {
2311 if (targetGUID == ihit->targetGUID) // Found in list
2312 {
2313 ihit->effectMask |= effectMask; // Immune effects removed from mask
2314 ihit->scaleAura = false;
2315 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2316 {
2317 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2318 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2319 ihit->scaleAura = true;
2320 }
2321
2322 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2323 return;
2324 }
2325 }
2326
2327 // This is new target calculate data for him
2328
2329 // Get spell hit result on target
2330 TargetInfo targetInfo;
2331 targetInfo.targetGUID = targetGUID; // Store target GUID
2332 targetInfo.effectMask = effectMask; // Store all effects not immune
2333 targetInfo.processed = false; // Effects not apply on target
2334 targetInfo.alive = target->IsAlive();
2335 targetInfo.damage = 0;
2336 targetInfo.crit = false;
2337 targetInfo.scaleAura = false;
2338 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2339 {
2340 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2341 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2342 targetInfo.scaleAura = true;
2343 }
2344
2345 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2346
2347 // Calculate hit result
2348 if (m_originalCaster)
2349 {
2350 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2351 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2352 {
2353 targetInfo.missCondition = SPELL_MISS_NONE;
2354 }
2355 }
2356 else
2357 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2358
2359 // Spell have speed - need calculate incoming time
2360 // Incoming time is zero for self casts. At least I think so.
2361 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2362 {
2363 // calculate spell incoming interval
2365 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2366
2367 if (dist < 5.0f)
2368 dist = 5.0f;
2369 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2370
2371 // Calculate minimum incoming time
2372 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2373 m_delayMoment = targetInfo.timeDelay;
2374 }
2375 else
2376 targetInfo.timeDelay = 0LL;
2377
2378 // If target reflect spell back to caster
2379 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2380 {
2381 // Calculate reflected spell result on caster
2383
2384 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2385 targetInfo.reflectResult = SPELL_MISS_PARRY;
2386
2387 // Increase time interval for reflected spells by 1.5
2389 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2390
2392
2393 // HACK: workaround check for succubus seduction case
2395 if (m_caster->IsPet())
2396 {
2397 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2398 switch (ci->family)
2399 {
2401 {
2402 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2403 cancel();
2404 }
2405 break;
2406 return;
2407 }
2408 }
2409 }
2410 else
2411 targetInfo.reflectResult = SPELL_MISS_NONE;
2412
2413 // Add target to list
2414 m_UniqueTargetInfo.push_back(targetInfo);
2415}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1699
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2665
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1534
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1537
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1536
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1541
@ SPELL_FLAG_REFLECTED
Definition Spell.h:85
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Spell.h:853
Definition SpellInfo.h:316
uint32 SpellLevel
Definition SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2397
uint32 SpellIconID
Definition SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition SpellInfo.cpp:1643
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:7916
bool IsAlive() const
Definition Unit.h:1773
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3504
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition Unit.cpp:13181
uint8 GetLevel() const
Definition Unit.h:1088
EventProcessor m_Events
Definition Object.h:731
Definition CreatureData.h:186
uint32 family
Definition CreatureData.h:217
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122
Definition Spell.h:265
bool processed
Definition Spell.h:271
int32 damage
Definition Spell.h:275
SpellMissInfo missCondition
Definition Spell.h:268
bool scaleAura
Definition Spell.h:274
bool crit
Definition Spell.h:273
uint64 timeDelay
Definition Spell.h:267
ObjectGuid targetGUID
Definition Spell.h:266
SpellMissInfo reflectResult
Definition Spell.h:269
bool alive
Definition Spell.h:272
uint8 effectMask
Definition Spell.h:270

References EventProcessor::AddEventAtOffset(), TargetInfo::alive, cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, WorldObject::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
901{
902 if (m_targets.HasDst())
903 {
904 if (m_targets.HasTraj())
905 {
906 float speed = m_targets.GetSpeedXY();
907 if (speed > 0.0f)
908 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
909 }
910 else if (m_spellInfo->Speed > 0.0f)
911 {
912 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
913 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
914 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
915 }
916 }
917
918 return 0;
919}
bool HasTraj() const
Definition Spell.h:176
bool HasDst() const
Definition Spell.h:175
float GetSpeedXY() const
Definition Spell.h:184
float GetDist2d() const
Definition Spell.h:183
WorldLocation const * GetDstPos() const
Definition Spell.cpp:400
float GetExactDist(float x, float y, float z) const
Definition Position.h:182

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1154{
1156 if (Creature* creature = m_caster->ToCreature())
1157 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1158
1159 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1160 if (multiplier <= 0.0f)
1161 multiplier = 1.0f;
1162
1163 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1164
1165 float duration = dist / speedXY;
1166 float durationSqr = duration * duration;
1167 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1168 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1169 float height;
1170 if (durationSqr < minHeight * 8 / Movement::gravity)
1171 height = minHeight;
1172 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1173 height = maxHeight;
1174 else
1175 height = Movement::gravity * durationSqr / 8;
1176
1177 speedZ = std::sqrt(2 * Movement::gravity * height);
1178}
@ MOVE_RUN
Definition UnitDefines.h:354
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:76
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:89
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:14597
double gravity
Definition MovementUtil.cpp:24

References baseMoveSpeed, SpellInfo::Effects, Unit::GetSpeed(), Movement::gravity, Unit::IsControlledByPlayer(), m_caster, m_spellInfo, MOVE_RUN, playerBaseMoveSpeed, and Object::ToCreature().

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition Unit.cpp:14965
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:223

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8548{
8549 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8550 {
8551 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8552 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8553 for (; hookItr != hookItrEnd; ++hookItr)
8554 (*hookItr).Call(*scritr);
8555
8556 (*scritr)->_FinishScriptCall();
8557 }
8558}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8660{
8661 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8662 {
8663 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8664 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8665 for (; hookItr != hookItrEnd; ++hookItr)
8666 (*hookItr).Call(*scritr);
8667
8668 (*scritr)->_FinishScriptCall();
8669 }
8670}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8522{
8523 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8524 {
8525 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8526 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8527 for (; hookItr != hookItrEnd; ++hookItr)
8528 (*hookItr).Call(*scritr);
8529
8530 (*scritr)->_FinishScriptCall();
8531 }
8532}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8634{
8635 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8636 {
8637 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8638 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8639 for (; hookItr != hookItrEnd; ++hookItr)
8640 (*hookItr).Call(*scritr, missInfo);
8641
8642 (*scritr)->_FinishScriptCall();
8643 }
8644}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8561{
8563 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8564 {
8565 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8566 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8567 for (; hookItr != hookItrEnd; ++hookItr)
8568 {
8569 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8570 if (retVal == SPELL_CAST_OK)
8571 retVal = tempResult;
8572 }
8573
8574 (*scritr)->_FinishScriptCall();
8575 }
8576 return retVal;
8577}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8701{
8702 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8703 {
8704 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8705 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8706 for (; hookItr != hookItrEnd; ++hookItr)
8707 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8708 hookItr->Call(*scritr, target);
8709
8710 (*scritr)->_FinishScriptCall();
8711 }
8712}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8586{
8587 // execute script effect handler hooks and check if effects was prevented
8588 bool preventDefault = false;
8589 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8590 {
8591 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8592 SpellScriptHookType hookType;
8593 switch (mode)
8594 {
8596 effItr = (*scritr)->OnEffectLaunch.begin();
8597 effEndItr = (*scritr)->OnEffectLaunch.end();
8599 break;
8601 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8602 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8604 break;
8606 effItr = (*scritr)->OnEffectHit.begin();
8607 effEndItr = (*scritr)->OnEffectHit.end();
8609 break;
8611 effItr = (*scritr)->OnEffectHitTarget.begin();
8612 effEndItr = (*scritr)->OnEffectHitTarget.end();
8614 break;
8615 default:
8616 ABORT();
8617 return false;
8618 }
8619 (*scritr)->_PrepareScriptCall(hookType);
8620 for (; effItr != effEndItr; ++effItr)
8621 // effect execution can be prevented
8622 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8623 (*effItr).Call(*scritr, effIndex);
8624
8625 if (!preventDefault)
8626 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8627
8628 (*scritr)->_FinishScriptCall();
8629 }
8630 return preventDefault;
8631}
#define ABORT
Definition Errors.h:76
SpellScriptHookType
Definition SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition SpellScript.h:162
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:245
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:247

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8673{
8674 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8675 {
8676 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8677 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8678 for (; hookItr != hookItrEnd; ++hookItr)
8679 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8680 hookItr->Call(*scritr, targets);
8681
8682 (*scritr)->_FinishScriptCall();
8683 }
8684}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8687{
8688 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8689 {
8690 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8691 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8692 for (; hookItr != hookItrEnd; ++hookItr)
8693 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8694 hookItr->Call(*scritr, target);
8695
8696 (*scritr)->_FinishScriptCall();
8697 }
8698}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8535{
8536 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8537 {
8538 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8539 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8540 for (; hookItr != hookItrEnd; ++hookItr)
8541 (*hookItr).Call(*scritr);
8542
8543 (*scritr)->_FinishScriptCall();
8544 }
8545}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8647{
8648 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8649 {
8650 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8651 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8652 for (; hookItr != hookItrEnd; ++hookItr)
8653 (*hookItr).Call(*scritr);
8654
8655 (*scritr)->_FinishScriptCall();
8656 }
8657}
@ SPELL_SCRIPT_HOOK_HIT
Definition SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6977{
6978 ObjectGuid targetguid = target->GetGUID();
6979
6980 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
6981 {
6982 if (!spellEffectInfo.IsAura())
6983 continue;
6984
6985 AuraType const& auraType = spellEffectInfo.ApplyAuraName;
6986 Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
6987 for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
6988 {
6989 if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
6990 return false;
6991
6992 switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
6993 {
6995 return false;
6997 if (GetCaster() == (*auraIt)->GetCaster())
6998 return false;
6999 break;
7000 case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
7002 if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
7003 return false;
7004 break;
7006 default:
7007 break;
7008 }
7009 }
7010 }
7011
7012 SpellCastResult result = CheckPetCast(target);
7013
7014 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7015 {
7017 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7018 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7019 if (ihit->targetGUID == targetguid)
7020 return true;
7021 }
7022 return false; //target invalid
7023}
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1094
AuraType
Definition SpellAuraDefines.h:62
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER
Definition SpellMgr.h:367
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE
Definition SpellMgr.h:366
@ SPELL_GROUP_STACK_RULE_DEFAULT
Definition SpellMgr.h:365
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT
Definition SpellMgr.h:368
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST
Definition SpellMgr.h:369
Definition SpellInfo.h:249
Unit * GetCaster() const
Definition Spell.h:585
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:6783

References CheckPetCast(), Unit::GetAuraEffectsByType(), GetCaster(), SpellInfo::GetEffects(), Object::GetGUID(), GetSpellInfo(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, SelectSpellTargets(), SPELL_CAST_OK, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_GROUP_STACK_RULE_DEFAULT, SPELL_GROUP_STACK_RULE_EXCLUSIVE, SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER, SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST, SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT, and sSpellMgr.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3648{
3650 return;
3651
3652 uint32 oldState = m_spellState;
3654
3655 m_autoRepeat = false;
3656 switch (oldState)
3657 {
3661
3662 if (m_caster->IsPlayer())
3663 {
3665 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3666 }
3667 [[fallthrough]];
3670 break;
3672 if (!bySelf)
3673 {
3674 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3675 if ((*ihit).missCondition == SPELL_MISS_NONE)
3676 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3677 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3678
3681
3684 }
3685
3687 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3688
3689 // spell is canceled-take mods and clear list
3690 if (Player* player = m_caster->GetSpellModOwner())
3691 player->RemoveSpellMods(this);
3692
3693 m_appliedMods.clear();
3694 break;
3695 default:
3696 break;
3697 }
3698
3700 if (m_selfContainer && *m_selfContainer == this)
3701 *m_selfContainer = nullptr;
3702
3703 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3705 {
3707 }
3708
3709 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3711
3712 //set state back so finish will be processed
3713 m_spellState = oldState;
3714
3715 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3716
3717 finish(false);
3718}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition SharedDefines.h:861
@ SPELL_FAILED_INTERRUPTED
Definition SharedDefines.h:1000
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition Spell.h:235
@ SPELL_STATE_CASTING
Definition Spell.h:236
bool NeedSendSpectatorData() const
Definition Player.cpp:15504
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5140
void CancelGlobalCooldown()
Definition Spell.cpp:8888
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:571
UsedSpellMods m_appliedMods
Definition Spell.h:556
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6431
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6375
Map * FindMap() const
Definition Object.h:621
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition ArenaSpectator.h:80

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, sScriptMgr, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8889{
8891 return;
8892
8893 // Cancel global cooldown when interrupting current cast
8895 return;
8896
8897 // Only players or controlled units have global cooldown
8898 if (m_caster->GetCharmInfo())
8900 else if (m_caster->IsPlayer())
8902}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:545
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1819
uint32 StartRecoveryTime
Definition SpellInfo.h:351
CharmInfo * GetCharmInfo()
Definition Unit.h:1266
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1561
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition CharmInfo.h:160

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8738{
8739 // Relentless strikes, proc only from first effect
8740 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8741 return effMask & (1 << EFFECT_0);
8742
8743 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8744 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8745 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8746 {
8747 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8748 return true;
8749 }
8750 return effMask;
8751}
@ EFFECT_0
Definition SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1421
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition SharedDefines.h:542

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8353{
8354 if (!lockId) // possible case for GO and maybe for items.
8355 return SPELL_CAST_OK;
8356
8357 // Get LockInfo
8358 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8359
8360 if (!lockInfo)
8362
8363 bool reqKey = false; // some locks not have reqs
8364
8365 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8366 {
8367 switch (lockInfo->Type[j])
8368 {
8369 // check key item (many fit cases can be)
8370 case LOCK_KEY_ITEM:
8371 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8372 return SPELL_CAST_OK;
8373 reqKey = true;
8374 break;
8375 // check key skill (only single first fit case can be)
8376 case LOCK_KEY_SKILL:
8377 {
8378 reqKey = true;
8379
8380 // wrong locktype, skip
8381 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8382 continue;
8383
8384 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8385
8386 if (skillId != SKILL_NONE)
8387 {
8388 reqSkillValue = lockInfo->Skill[j];
8389
8390 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8391 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8392 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8393
8394 // skill bonus provided by casting spell (mostly item spells)
8395 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8396 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8398 {
8399 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8400 }
8401
8402 if (skillValue < reqSkillValue)
8404 }
8405
8406 return SPELL_CAST_OK;
8407 }
8408 case LOCK_KEY_SPELL:
8409 {
8410 if (m_spellInfo->Id == lockInfo->Index[j])
8411 {
8412 return SPELL_CAST_OK;
8413 }
8414 reqKey = true;
8415 break;
8416 }
8417 }
8418 }
8419
8420 if (reqKey)
8422
8423 return SPELL_CAST_OK;
8424}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1305
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition SharedDefines.h:1441
LockType
Definition SharedDefines.h:2602
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2596
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2597
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2598
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:972
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:1009
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3260
@ SKILL_NONE
Definition SharedDefines.h:3104
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3215
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5443
bool IsAbilityOfSkillType(uint32 skillType) const
Definition SpellInfo.cpp:1005
Definition DBCStructure.h:1308
uint32 Type[MAX_LOCK_CASE]
Definition DBCStructure.h:1310
uint32 Index[MAX_LOCK_CASE]
Definition DBCStructure.h:1311
uint32 Skill[MAX_LOCK_CASE]
Definition DBCStructure.h:1312

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3721{
3722 Player* modOwner = m_caster->GetSpellModOwner();
3723 Spell* lastMod = nullptr;
3724 if (modOwner)
3725 {
3726 lastMod = modOwner->m_spellModTakingSpell;
3727 if (lastMod)
3728 modOwner->SetSpellModTakingSpell(lastMod, false);
3729 }
3730
3731 _cast(skipCheck);
3732
3733 if (lastMod)
3734 modOwner->SetSpellModTakingSpell(lastMod, true);
3735}
Spell * m_spellModTakingSpell
Definition Player.h:2589
Definition Spell.h:295
void _cast(bool skipCheck)
Definition Spell.cpp:3737

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5604{
5605 // check death state
5608
5609 // Spectator check
5610 if (m_caster->IsPlayer())
5611 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5612 return SPELL_FAILED_NOT_HERE;
5613
5615
5616 sScriptMgr->OnSpellCheckCast(this, strict, res);
5617
5618 if (res != SPELL_CAST_OK)
5619 return res;
5620
5621 // check cooldowns to prevent cheating
5623 {
5624 if (m_caster->IsPlayer())
5625 {
5626 //can cast triggered (by aura only?) spells while have this flag
5629
5631 {
5634 else
5636 }
5637
5638 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5641 }
5644 }
5645
5647 {
5650 }
5651
5652 // Check global cooldown
5655
5656 // only triggered spells can be processed an ended battleground
5657 if (!IsTriggered() && m_caster->IsPlayer())
5659 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5661
5662 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5663 {
5665 !m_caster->IsOutdoors())
5667
5671 }
5672
5673 // only check at first call, Stealth auras are already removed at second call
5674 // for now, ignore triggered spells
5676 {
5677 bool checkForm = true;
5678 // Ignore form req aura
5680 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5681 {
5682 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5683 continue;
5684 checkForm = false;
5685 break;
5686 }
5687 if (checkForm)
5688 {
5689 // Cannot be used in this stance/form
5691 if (shapeError != SPELL_CAST_OK)
5692 return shapeError;
5693
5696 }
5697 }
5698
5700 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5701 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5703
5704 bool reqCombat = true;
5706 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5707 {
5708 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5709 {
5710 m_needComboPoints = false;
5711 if ((*j)->GetMiscValue() == 1)
5712 {
5713 reqCombat = false;
5714 break;
5715 }
5716 }
5717 }
5718
5719 // caster state requirements
5720 // not for triggered spells (needed by execute)
5722 {
5727
5728 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5733
5734 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5736 }
5737
5738 // Xinef: exploit protection
5740 {
5741 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5742 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5743 if (instanceScript->IsEncounterInProgress())
5744 {
5745 if (Group* group = m_caster->ToPlayer()->GetGroup())
5746 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5747 if (Player* member = itr->GetSource())
5748 if (member->IsInMap(m_caster))
5749 if (Unit* victim = member->GetVictim())
5750 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5751 {
5752 m_caster->CombatStart(victim);
5753 victim->AddThreat(m_caster, 1.0f);
5754 break;
5755 }
5757 }
5758 }
5759
5760 // cancel autorepeat spells if cast start when moving
5761 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5762 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5763 {
5764 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5767 return SPELL_FAILED_MOVING;
5768 }
5769
5770 Vehicle* vehicle = m_caster->GetVehicle();
5772 {
5773 uint16 checkMask = 0;
5774 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5775 {
5776 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5778 {
5779 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5780 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5781 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5782 break;
5783 }
5784 }
5785
5788
5789 if (!checkMask)
5790 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5791
5792 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5793 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5795 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5797 }
5798
5799 // check spell cast conditions from database
5800 {
5803 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5804 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5805 {
5806 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5807 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5808 {
5812 }
5813 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5816 }
5817 }
5818
5819 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5820 // those spells may have incorrect target entries or not filled at all (for example 15332)
5821 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5822 // also, such casts shouldn't be sent to client
5823 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5825 {
5826 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5827 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5829 {
5831 if (castResult != SPELL_CAST_OK)
5832 return castResult;
5833 }
5834 }
5835
5836 if (Unit* target = m_targets.GetUnitTarget())
5837 {
5838 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5839 if (castResult != SPELL_CAST_OK)
5840 return castResult;
5841
5842 if (target != m_caster)
5843 {
5844 // Must be behind the target
5845 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5847
5848 // Target must be facing you
5849 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5851
5854 {
5855 bool castedByGameobject = false;
5856 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5858 {
5859 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5860 }
5861 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5862 {
5863 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5864 {
5865 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5866 }
5867 }
5868
5869 if (castedByGameobject)
5870 {
5871 // If spell casted by gameobject then ignore M2 models
5872 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5873 }
5874
5876 {
5878 }
5879 }
5880 }
5881 }
5882
5883 // Check for line of sight for spells with dest
5884 if (m_targets.HasDst())
5885 {
5886 float x, y, z;
5887 m_targets.GetDstPos()->GetPosition(x, y, z);
5888
5891 {
5892 bool castedByGameobject = false;
5893 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5895 {
5896 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5897 }
5898 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5899 {
5900 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5901 {
5902 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5903 }
5904 }
5905
5906 if (castedByGameobject)
5907 {
5908 // If spell casted by gameobject then ignore M2 models
5909 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5910 }
5911
5913 {
5915 }
5916 }
5917 }
5918
5919 // check pet presence
5920 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5921 {
5922 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5923 {
5925 {
5926 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5928 else
5929 return SPELL_FAILED_NO_PET;
5930 }
5931 break;
5932 }
5933 }
5934 // Spell casted only on battleground
5936 if (!m_caster->ToPlayer()->InBattleground())
5938
5939 // do not allow spells to be cast in arenas
5940 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5941 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5944 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5945 if (mapEntry->IsBattleArena())
5947
5948 // zone check
5950 {
5951 uint32 zone, area;
5952 m_caster->GetZoneAndAreaId(zone, area);
5953
5955 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5956 if (locRes != SPELL_CAST_OK)
5957 return locRes;
5958 }
5959
5960 // not let players cast spells at mount (and let do it to creatures)
5963 {
5964 if (m_caster->IsInFlight())
5966 else
5968 }
5969
5970 SpellCastResult castResult = SPELL_CAST_OK;
5971
5972 // always (except passive spells) check items (focus object can be required for any type casts)
5973 if (!m_spellInfo->IsPassive())
5974 {
5975 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
5976 castResult = CheckSpellFocus();
5977 if (castResult != SPELL_CAST_OK)
5978 return castResult;
5979
5980 castResult = CheckItems();
5981 if (castResult != SPELL_CAST_OK)
5982 return castResult;
5983 }
5984
5985 // Triggered spells also have range check
5987 castResult = CheckRange(strict);
5988 if (castResult != SPELL_CAST_OK)
5989 return castResult;
5990
5992 {
5993 castResult = CheckPower();
5994 if (castResult != SPELL_CAST_OK)
5995 return castResult;
5996 }
5997
5999 {
6000 return SPELL_CAST_OK;
6001 }
6002
6003 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6005 {
6007 if (castResult != SPELL_CAST_OK)
6008 return castResult;
6009
6010 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6012 {
6014 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6015 if (itr->type == m_spellInfo->Mechanic)
6017 }
6018 }
6019
6020 // script hook
6021 castResult = CallScriptCheckCastHandlers();
6022 if (castResult != SPELL_CAST_OK)
6023 return castResult;
6024
6025 bool hasDispellableAura = false;
6026 bool hasNonDispelEffect = false;
6027 uint32 dispelMask = 0;
6028 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6029 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6030 {
6032 {
6033 hasDispellableAura = true;
6034 break;
6035 }
6036
6037 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6038 }
6039 else if (m_spellInfo->Effects[i].IsEffect())
6040 {
6041 hasNonDispelEffect = true;
6042 break;
6043 }
6044
6045 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6046 {
6047 if (Unit* target = m_targets.GetUnitTarget())
6048 {
6049 // Xinef: do not allow to cast on hostile targets in sanctuary
6050 if (!m_caster->IsFriendlyTo(target))
6051 {
6052 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6053 {
6054 // Xinef: fix for duels
6055 Player* player = m_caster->ToPlayer();
6056 if (!player || !player->duel || target != player->duel->Opponent)
6058 }
6059 }
6060
6061 DispelChargesList dispelList;
6062 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6063
6064 if (dispelList.empty())
6066 }
6067 }
6068
6069 uint8 approximateAuraEffectMask = 0;
6070 uint8 nonAuraEffectMask = 0;
6071 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6072 {
6073 // for effects of spells that have only one target
6074 switch (m_spellInfo->Effects[i].Effect)
6075 {
6077 {
6078 if (!m_caster->IsPlayer())
6080
6081 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6082 break;
6083
6084 Pet* pet = m_caster->ToPlayer()->GetPet();
6085
6086 if (!pet)
6087 return SPELL_FAILED_NO_PET;
6088
6089 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6090
6091 if (!learn_spellproto)
6093
6094 if (m_spellInfo->SpellLevel > pet->GetLevel())
6095 return SPELL_FAILED_LOWLEVEL;
6096
6097 break;
6098 }
6100 {
6101 // check target only for unit target case
6103 {
6104 if (!m_caster->IsPlayer())
6106
6107 Pet* pet = unitTarget->ToPet();
6108 if (!pet || pet->GetOwner() != m_caster)
6110
6111 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6112
6113 if (!learn_spellproto)
6115
6116 if (m_spellInfo->SpellLevel > pet->GetLevel())
6117 return SPELL_FAILED_LOWLEVEL;
6118 }
6119 break;
6120 }
6122 {
6123 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6124 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6125 if (m_caster->HasAura(gp->SpellId))
6127 break;
6128 }
6130 {
6131 if (!m_caster->IsPlayer())
6133
6134 Item* foodItem = m_targets.GetItemTarget();
6135 if (!foodItem)
6137
6138 Pet* pet = m_caster->ToPlayer()->GetPet();
6139
6140 if (!pet)
6141 return SPELL_FAILED_NO_PET;
6142
6143 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6145
6146 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6148
6149 if (m_caster->IsInCombat() || pet->IsInCombat())
6151
6152 break;
6153 }
6156 {
6157 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6158 if (m_caster->IsPlayer())
6159 if (Unit* target = m_targets.GetUnitTarget())
6160 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6162 break;
6163 }
6165 {
6167 {
6169 }
6170
6172 {
6173 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6174 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6176 }
6178 {
6179 // Exception for Master's Call
6180 if (m_spellInfo->Id != 54216)
6181 {
6182 return SPELL_FAILED_ROOTED;
6183 }
6184 }
6185 if (m_caster->IsPlayer())
6186 if (Unit* target = m_targets.GetUnitTarget())
6187 if (!target->IsAlive())
6189 // Xinef: Pass only explicit unit target spells
6190 // pussywizard:
6191 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6192 {
6193 Unit* target = m_targets.GetUnitTarget();
6194 if (!target)
6196
6197 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6198 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6200
6201 float objSize = target->GetCombatReach();
6202 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6203
6204 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6205 m_preGeneratedPath->SetPathLengthLimit(range);
6206
6207 // first try with raycast, if it fails fall back to normal path
6208 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6209 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6210 return SPELL_FAILED_NOPATH;
6211 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6212 return SPELL_FAILED_NOPATH;
6213 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6214 return SPELL_FAILED_NOPATH;
6215
6216 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6217 }
6218 if (Player* player = m_caster->ToPlayer())
6219 player->SetCanTeleport(true);
6220 break;
6221 }
6223 {
6226
6229
6230 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6231 if (!creature->IsCritter() && !creature->loot.isLooted())
6233
6234 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6235
6236 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6237 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6238 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6239 if (ReqValue > skillValue)
6241
6242 break;
6243 }
6245 {
6246 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6247 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6248 break;
6249
6250 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6251 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6252 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6254
6255 Item* pTempItem = nullptr;
6257 {
6258 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6259 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6260 }
6263
6264 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6265 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6267 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6269
6270 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6271 if (GameObject* go = m_targets.GetGOTarget())
6272 {
6273 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6274 {
6276 }
6277 }
6278 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6280 {
6281 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6282 {
6283 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6285 }
6286 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6289 }
6290
6291 // get the lock entry
6292 uint32 lockId = 0;
6293 if (GameObject* go = m_targets.GetGOTarget())
6294 {
6295 lockId = go->GetGOInfo()->GetLockId();
6296 if (!lockId)
6298 }
6299 else if (Item* itm = m_targets.GetItemTarget())
6300 lockId = itm->GetTemplate()->LockID;
6301
6302 SkillType skillId = SKILL_NONE;
6303 int32 reqSkillValue = 0;
6304 int32 skillValue = 0;
6305
6306 // check lock compatibility
6307 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6308 if (res != SPELL_CAST_OK)
6309 return res;
6310
6311 // chance for fail at lockpicking attempt
6312 // second check prevent fail at rechecks
6313 // herbalism and mining cannot fail as of patch 3.1.0
6314 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6315 {
6316 // chance for failure in orange lockpick
6317 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6318 {
6320 }
6321 }
6322 break;
6323 }
6325 {
6326 Unit* unitCaster = m_caster->ToUnit();
6327 if (!unitCaster)
6328 {
6330 }
6331
6332 Creature* pet = unitCaster->GetGuardianPet();
6333 if (pet)
6334 {
6335 if (pet->IsAlive())
6336 {
6338 }
6339 }
6340 else if (Player* playerCaster = m_caster->ToPlayer())
6341 {
6342 PetStable& petStable = playerCaster->GetOrInitPetStable();
6343 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6344 {
6345 return SPELL_FAILED_NO_PET;
6346 }
6347 }
6348
6349 break;
6350 }
6351 // This is generic summon effect
6353 {
6354 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6355 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6356 break;
6357 switch (SummonProperties->Category)
6358 {
6360 if (m_caster->GetPetGUID())
6362 [[fallthrough]];
6364 if (m_caster->GetCharmGUID())
6366 break;
6367 }
6368 break;
6369 }
6371 {
6373 {
6378 }
6379 break;
6380 }
6382 {
6383 Unit* unitCaster = m_caster->ToUnit();
6384 if (!unitCaster)
6386
6388 {
6389 if (m_caster->GetPetGUID())
6391 if (m_caster->GetCharmGUID())
6393 }
6394
6396 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6397 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6398
6399 Player* playerCaster = unitCaster->ToPlayer();
6400 if (playerCaster && playerCaster->GetPetStable())
6401 {
6402 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6403 if (info.first)
6404 {
6405 if (info.first->Type == HUNTER_PET)
6406 {
6407 if (!info.first->Health)
6408 {
6409 playerCaster->SendTameFailure(PET_TAME_DEAD);
6411 }
6412
6413 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6414 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6415 {
6416 // if problem in exotic pet
6417 if (creatureInfo && creatureInfo->IsTameable(true))
6419 else
6421
6423 }
6424 }
6425 }
6426 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6427 {
6430 }
6431 }
6432 break;
6433 }
6435 {
6436 if (!m_caster->IsPlayer())
6438 if (!m_caster->GetTarget())
6440
6442 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6444
6445 // Xinef: Implement summon pending error
6446 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6448
6449 // check if our map is dungeon
6450 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6451 if (map->IsDungeon())
6452 {
6453 uint32 mapId = m_caster->GetMap()->GetId();
6454 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6455 /*if (map->IsRaid())
6456 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6457 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6458 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6459
6460 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6461 if (!instance)
6463 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6465 }
6466 break;
6467 }
6468 // RETURN HERE
6470 {
6471 if (!m_caster->IsPlayer())
6473
6474 Player* playerCaster = m_caster->ToPlayer();
6475 //
6476 if (!(playerCaster->GetTarget()))
6478
6480
6481 if (!target ||
6482 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6484
6485 // Xinef: Implement summon pending error
6486 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6488
6489 break;
6490 }
6491 case SPELL_EFFECT_LEAP:
6493 {
6494 //Do not allow to cast it before BG starts.
6495 if (m_caster->IsPlayer())
6496 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6497 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6499 break;
6500 }
6502 {
6505
6506 bool found = false;
6508 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6509 {
6510 if (itr->second->GetBase()->IsPassive())
6511 continue;
6512
6513 if (!itr->second->IsPositive())
6514 continue;
6515
6516 found = true;
6517 break;
6518 }
6519
6520 if (!found)
6522
6523 break;
6524 }
6526 {
6528 {
6529 if (m_caster->IsPlayer())
6530 return SPELL_FAILED_ROOTED;
6531 else
6533 }
6534 break;
6535 }
6536 // xinef: do not allow to use leaps while rooted
6537 case SPELL_EFFECT_JUMP:
6539 {
6541 return SPELL_FAILED_ROOTED;
6542 break;
6543 }
6545 if (!sScriptMgr->CanSelectSpecTalent(this))
6547 // can't change during already started arena/battleground
6548 if (m_caster->IsPlayer())
6549 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6550 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6552 break;
6553 default:
6554 break;
6555 }
6556
6557 if (m_spellInfo->Effects[i].IsAura())
6558 approximateAuraEffectMask |= 1 << i;
6559 else if (m_spellInfo->Effects[i].IsEffect())
6560 nonAuraEffectMask |= 1 << i;
6561 }
6562
6563 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6564 {
6565 switch (m_spellInfo->Effects[i].ApplyAuraName)
6566 {
6567 case SPELL_AURA_DUMMY:
6568 break;
6570 {
6571 if (!m_caster->IsPlayer())
6572 return SPELL_FAILED_NO_PET;
6573
6574 Pet* pet = m_caster->ToPlayer()->GetPet();
6575 if (!pet)
6576 return SPELL_FAILED_NO_PET;
6577
6578 if (pet->GetCharmerGUID())
6579 return SPELL_FAILED_CHARMED;
6580 break;
6581 }
6585 {
6586 if (m_caster->GetCharmerGUID())
6587 return SPELL_FAILED_CHARMED;
6588
6589 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6591 {
6592 if (m_caster->GetPetGUID())
6594
6595 if (m_caster->GetCharmGUID())
6597 }
6598 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6599 {
6600 if (m_caster->GetCharmGUID())
6602 }
6603
6604 if (Unit* target = m_targets.GetUnitTarget())
6605 {
6606 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6608
6609 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6610 // but keep the old restriction for everything else.
6611 if (target->IsMounted())
6612 {
6613 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6615 }
6616
6617 if (target->GetCharmerGUID())
6618 return SPELL_FAILED_CHARMED;
6619
6620 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6622
6623 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6625
6626 int32 damage = CalculateSpellDamage(i, target);
6627 if (damage && int32(target->GetLevel()) > damage)
6629 }
6630
6631 break;
6632 }
6633 case SPELL_AURA_MOUNTED:
6634 {
6635 // Disallow casting flying mounts in water
6638
6639 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6640 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6641 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6642 if (it)
6643 allowMount = it->AllowMount;
6644 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6646
6649
6650 // xinef: dont allow to cast mounts in specific transforms
6651 if (m_caster->getTransForm())
6652 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6653 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6654 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6656
6657 break;
6658 }
6660 {
6661 if (!m_targets.GetUnitTarget())
6663
6664 // can be casted at non-friendly unit or own pet/charm
6667
6668 break;
6669 }
6670 case SPELL_AURA_FLY:
6672 {
6673 // Xinef: added water check
6674 if (m_caster->IsInWater())
6676
6677 // not allow cast fly spells if not have req. skills (all spells is self target)
6678 // allow always ghost flight spells
6680 {
6681 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6682 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6683 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6684 return SPELL_FAILED_NOT_HERE;
6685 }
6686 break;
6687 }
6689 {
6690 if (m_spellInfo->Effects[i].IsTargetingArea())
6691 break;
6692
6693 if (!m_caster->IsPlayer() || m_CastItem)
6694 break;
6695
6696 if (!m_targets.GetUnitTarget())
6698
6701
6702 break;
6703 }
6704 case SPELL_AURA_HOVER:
6705 {
6707 {
6709 }
6710 break;
6711 }
6713 {
6714 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6715 {
6717 }
6718 break;
6719 }
6720 default:
6721 break;
6722 }
6723
6724 // check if target already has the same type, but more powerful aura
6725 if (!nonAuraEffectMask && (approximateAuraEffectMask & (1 << i)) && !m_spellInfo->IsTargetingArea())
6726 if (Unit* target = m_targets.GetUnitTarget())
6727 if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, AuraType(m_spellInfo->Effects[i].ApplyAuraName),
6728 m_spellInfo->Effects[i].CalcValue(m_caster, &m_spellValue->EffectBasePoints[i]), approximateAuraEffectMask, false))
6730 }
6731
6732 // check trade slot case (last, for allow catch any another cast problems)
6734 {
6735 if (m_CastItem)
6737
6738 if (!m_caster->IsPlayer())
6740
6741 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6742
6743 if (!my_trade)
6745
6747 if (slot != TRADE_SLOT_NONTRADED)
6749
6750 if (!IsTriggered())
6751 if (my_trade->GetSpell())
6753 }
6754
6755 // check if caster has at least 1 combo point on target for spells that require combo points
6757 {
6759 {
6761 {
6763 }
6764 }
6765 else
6766 {
6767 if (!m_caster->GetComboPoints())
6768 {
6770 }
6771 }
6772 }
6773
6774 // xinef: check relic cooldown
6778
6779 // all ok
6780 return SPELL_CAST_OK;
6781}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
#define sConditionMgr
Definition ConditionMgr.h:292
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:142
std::list< Condition * > ConditionList
Definition ConditionMgr.h:239
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:458
Difficulty
Definition DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition DBCEnums.h:262
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::uint16_t uint16
Definition Define.h:108
#define sDisableMgr
Definition DisableMgr.h:88
@ GO_STATE_READY
Definition GameObjectData.h:706
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:103
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:110
@ PATHFIND_NOPATH
Definition PathGenerator.h:50
@ PATHFIND_SHORT
Definition PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition PathGenerator.h:49
@ HUNTER_PET
Definition PetDefines.h:33
@ PLAYER_ALLOW_ONLY_ABILITY
Definition Player.h:483
int32 irand(int32 min, int32 max)
Definition Random.cpp:37
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1577
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1571
Powers
Definition SharedDefines.h:279
@ POWER_MANA
Definition SharedDefines.h:280
@ SPELL_ATTR7_DEBUG_SPELL
Definition SharedDefines.h:655
@ SPELL_EFFECT_LEAP
Definition SharedDefines.h:818
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:851
@ SPELL_EFFECT_STUCK
Definition SharedDefines.h:873
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition SharedDefines.h:941
@ SPELL_EFFECT_APPLY_GLYPH
Definition SharedDefines.h:863
@ SPELL_EFFECT_FEED_PET
Definition SharedDefines.h:890
@ SPELL_EFFECT_SUMMON_PLAYER
Definition SharedDefines.h:874
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:831
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition SharedDefines.h:832
@ SPELL_EFFECT_RESURRECT_PET
Definition SharedDefines.h:898
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:927
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:817
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:797
@ SPELL_EFFECT_RESURRECT
Definition SharedDefines.h:807
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:885
@ SPELL_EFFECT_RESURRECT_NEW
Definition SharedDefines.h:902
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition SharedDefines.h:951
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:825
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:830
@ SPELL_EFFECT_SKINNING
Definition SharedDefines.h:884
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition SharedDefines.h:942
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:822
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition SharedDefines.h:915
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition SharedDefines.h:846
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1564
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:604
@ TARGET_UNIT_PET
Definition SharedDefines.h:1425
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1438
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:469
@ SPELL_ATTR1_INITIATE_COMBAT
Definition SharedDefines.h:439
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:515
@ PET_TAME_NOPET_AVAILABLE
Definition SharedDefines.h:3939
@ PET_TAME_DEAD
Definition SharedDefines.h:3942
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3944
@ CLASS_WARLOCK
Definition SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1410
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3788
SpellCustomErrors
Definition SharedDefines.h:1153
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition SharedDefines.h:1219
SpellAttr0
Definition SharedDefines.h:392
@ SPELL_ATTR0_ONLY_INDOORS
Definition SharedDefines.h:407
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition SharedDefines.h:419
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition SharedDefines.h:408
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition SharedDefines.h:417
@ SPELL_ATTR0_PASSIVE
Definition SharedDefines.h:399
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:416
@ SPELL_ATTR0_ONLY_STEALTHED
Definition SharedDefines.h:410
AuraStateType
Definition SharedDefines.h:1299
DispelType
Definition SharedDefines.h:1382
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition SharedDefines.h:1081
@ SPELL_FAILED_NOT_INFRONT
Definition SharedDefines.h:1021
@ SPELL_FAILED_MOVING
Definition SharedDefines.h:1011
@ SPELL_FAILED_NOT_MOUNTED
Definition SharedDefines.h:1024
@ SPELL_FAILED_AFFECTING_COMBAT
Definition SharedDefines.h:961
@ SPELL_FAILED_CASTER_AURASTATE
Definition SharedDefines.h:982
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition SharedDefines.h:1046
@ SPELL_FAILED_NOT_KNOWN
Definition SharedDefines.h:1023
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition SharedDefines.h:995
@ SPELL_FAILED_NOT_HERE
Definition SharedDefines.h:1020
@ SPELL_FAILED_ROOTED
Definition SharedDefines.h:1063
@ SPELL_FAILED_WRONG_PET_FOOD
Definition SharedDefines.h:1095
@ SPELL_FAILED_CUSTOM_ERROR
Definition SharedDefines.h:1132
@ SPELL_FAILED_SUMMON_PENDING
Definition SharedDefines.h:1143
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition SharedDefines.h:1106
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition SharedDefines.h:971
@ SPELL_FAILED_TRY_AGAIN
Definition SharedDefines.h:1092
@ SPELL_FAILED_NO_COMBO_POINTS
Definition SharedDefines.h:1038
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition SharedDefines.h:967
@ SPELL_FAILED_ALREADY_OPEN
Definition SharedDefines.h:968
@ SPELL_FAILED_NOT_TRADING
Definition SharedDefines.h:1031
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition SharedDefines.h:1047
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition SharedDefines.h:1043
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:1126
@ SPELL_FAILED_NOT_BEHIND
Definition SharedDefines.h:1017
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition SharedDefines.h:966
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition SharedDefines.h:1097
@ SPELL_FAILED_HIGHLEVEL
Definition SharedDefines.h:996
@ SPELL_FAILED_LOWLEVEL
Definition SharedDefines.h:1008
@ SPELL_FAILED_NOT_READY
Definition SharedDefines.h:1027
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:1102
@ SPELL_FAILED_NOT_IN_ARENA
Definition SharedDefines.h:1111
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition SharedDefines.h:1002
@ SPELL_FAILED_ONLY_STEALTHED
Definition SharedDefines.h:1055
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition SharedDefines.h:1078
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition SharedDefines.h:1048
@ SPELL_FAILED_AURA_BOUNCED
Definition SharedDefines.h:969
@ SPELL_FAILED_CANT_BE_CHARMED
Definition SharedDefines.h:973
@ SPELL_FAILED_CASTER_DEAD
Definition SharedDefines.h:983
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition SharedDefines.h:1115
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition SharedDefines.h:1142
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition SharedDefines.h:1146
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition SharedDefines.h:1086
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition SharedDefines.h:1028
@ SPELL_FAILED_UNIQUE_GLYPH
Definition SharedDefines.h:1136
@ SPELL_FAILED_ONLY_OUTDOORS
Definition SharedDefines.h:1053
@ SPELL_FAILED_CHARMED
Definition SharedDefines.h:984
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:1007
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition SharedDefines.h:1065
@ SPELL_FAILED_NO_PET
Definition SharedDefines.h:1044
@ SPELL_FAILED_NOPATH
Definition SharedDefines.h:1016
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition SharedDefines.h:1067
@ SPELL_FAILED_ONLY_INDOORS
Definition SharedDefines.h:1050
@ SPELL_FAILED_NOT_ON_TAXI
Definition SharedDefines.h:1025
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1075
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition SharedDefines.h:558
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition SharedDefines.h:557
@ SUMMON_CATEGORY_PET
Definition SharedDefines.h:3525
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3526
SkillType
Definition SharedDefines.h:3103
@ SKILL_MINING
Definition SharedDefines.h:3159
@ SKILL_HERBALISM
Definition SharedDefines.h:3155
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition SharedDefines.h:627
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition SpellDefines.h:135
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition SpellDefines.h:145
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition SpellDefines.h:146
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition SpellDefines.h:144
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition SpellDefines.h:134
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition SpellDefines.h:147
std::vector< SpellImmune > SpellImmuneList
Definition SpellDefines.h:182
@ TARGET_FLAG_UNIT_ENEMY
Definition SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:193
#define SPELL_RELIC_COOLDOWN
Definition SpellMgr.h:34
@ SPELL_FLAG_REDIRECTED
Definition Spell.h:86
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:382
@ CLASS_CONTEXT_PET
Definition UnitDefines.h:240
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition UnitDefines.h:310
@ SHAPESHIFT_FLAG_STANCE
Definition UnitDefines.h:104
@ UNIT_STATE_ROOT
Definition UnitDefines.h:180
@ UNIT_STATE_CHARGING
Definition UnitDefines.h:187
@ UNIT_FLAG_SKINNABLE
Definition UnitDefines.h:280
#define WORLD_TRIGGER
Definition Unit.h:39
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:79
Definition Battlefield.h:205
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition Battlefield.h:342
Definition Battleground.h:294
Loot loot
Definition Creature.h:228
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:205
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2794
Definition GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:169
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:295
bool IsBattlegroundOrArena() const
Definition Map.h:303
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2362
uint32 GetId() const
Definition Map.h:229
Difficulty GetDifficulty() const
Definition Map.h:290
uint64 GetRawValue() const
Definition ObjectGuid.h:142
bool IsPlayer() const
Definition ObjectGuid.h:168
bool IsGameObject() const
Definition ObjectGuid.h:171
Unit * ToUnit()
Definition Object.h:209
Definition PetDefines.h:212
Optional< PetInfo > CurrentPet
Definition PetDefines.h:235
std::vector< PetInfo > UnslottedPets
Definition PetDefines.h:238
Player * GetOwner() const
Definition Pet.cpp:2478
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1424
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1442
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition Pet.cpp:171
void SetCanTeleport(bool value)
Definition Player.h:2531
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1900
bool CanTameExoticPets() const
Definition Player.h:2206
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13240
bool InBattleground() const
Definition Player.h:2285
PetStable * GetPetStable()
Definition Player.h:1222
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12194
WorldSession * GetSession() const
Definition Player.h:2017
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16346
uint32 GetLastPotionId()
Definition Player.h:1826
Group * GetGroup()
Definition Player.h:2501
bool IsGameMaster() const
Definition Player.h:1175
time_t GetSummonExpireTimer() const
Definition Player.h:1117
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6775
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1124
std::unique_ptr< DuelInfo > duel
Definition Player.h:1892
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:409
GameObject * GetGOTarget() const
Definition Spell.cpp:263
ObjectGuid GetItemTargetGUID() const
Definition Spell.h:148
AuraType ApplyAuraName
Definition SpellInfo.h:254
int32 MiscValue
Definition SpellInfo.h:263
uint32 PreventionType
Definition SpellInfo.h:390
uint32 CasterAuraSpell
Definition SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1434
uint32 Mechanic
Definition SpellInfo.h:323
uint32 GetDispelMask() const
Definition SpellInfo.cpp:1932
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2292
bool IsSelfCast() const
Definition SpellInfo.cpp:1090
uint32 CasterAuraState
Definition SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1232
uint32 CasterAuraStateNot
Definition SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition SpellInfo.cpp:1489
SpellSchoolMask GetSchoolMask() const
Definition SpellInfo.cpp:1878
int32 AreaGroupId
Definition SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2217
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:1946
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1033
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:345
bool IsTargetingArea() const
Definition SpellInfo.cpp:1025
uint32 SpellFamilyName
Definition SpellInfo.h:387
uint32 AuraInterruptFlags
Definition SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1828
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:791
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:7739
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8352
SpellCastResult CheckItems()
Definition Spell.cpp:7156
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:488
SpellCastResult CheckPower()
Definition Spell.cpp:7111
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6819
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8560
bool IsTriggered() const
Definition Spell.h:564
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7025
bool HasGlobalCooldown() const
Definition Spell.cpp:8832
Definition TemporarySummon.h:50
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:790
Vehicle * GetVehicle() const
Definition Unit.h:1905
Unit * GetOwner() const
Definition Unit.cpp:10810
Pet * ToPet()
Definition Unit.h:719
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1320
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1936
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1321
bool IsInDisallowedMountForm() const
Definition Unit.cpp:21370
void CombatStart(Unit *target, bool initialAggro=true)
Definition Unit.cpp:13786
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:743
bool IsInSanctuary() const
Definition Unit.h:1028
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:834
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:5958
float GetCombatReach() const override
Definition Unit.h:867
UnitFlags GetUnitFlags() const
Definition Unit.h:736
TempSummon * ToTempSummon()
Definition Unit.h:721
bool HasStealthAura() const
Definition Unit.h:1821
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5847
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:677
bool IsInFlight() const
Definition Unit.h:1685
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2072
void SendTameFailure(uint8 result)
Definition Unit.cpp:19985
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5731
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:764
virtual bool IsInWater() const
Definition Unit.cpp:4395
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:10757
bool isMoving() const
Definition Unit.h:1688
ObjectGuid GetCharmGUID() const
Definition Unit.h:711
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1524
bool IsMounted() const
Definition Unit.h:1866
Unit * GetVictim() const
Definition Unit.h:893
bool IsCritter() const
Definition Unit.h:823
ObjectGuid GetOwnerGUID() const
Definition Unit.h:703
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4444
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:999
ObjectGuid GetCharmerGUID() const
Definition Unit.h:709
uint32 getTransForm() const
Definition Unit.h:1947
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1117
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5360
bool IsTotem() const
Definition Unit.h:789
Guardian * GetGuardianPet() const
Definition Unit.cpp:10861
ObjectGuid GetTarget() const
Definition Unit.h:851
bool IsInCombat() const
Definition Unit.h:924
ObjectGuid GetPetGUID() const
Definition Unit.h:713
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:606
uint32 GetMapId() const
Definition Position.h:281
Map * GetMap() const
Definition Object.h:620
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1214
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition Object.cpp:1373
bool IsOutdoors() const
Definition Object.cpp:3107
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1352
float GetVisibilityRange() const
Definition Object.cpp:1671
uint32 GetAreaId() const
Definition Object.cpp:3090
uint32 GetZoneId() const
Definition Object.cpp:3082
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3098
uint32 GetRecruiterId() const
Definition WorldSession.h:607
uint32 GetAccountId() const
Definition WorldSession.h:443
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition DBCStructure.h:519
Definition ConditionMgr.h:184
Condition * mLastFailedCondition
Definition ConditionMgr.h:186
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:185
uint32 ErrorType
Definition ConditionMgr.h:207
uint8 ConditionTarget
Definition ConditionMgr.h:211
uint32 ErrorTextId
Definition ConditionMgr.h:208
SkillType GetRequiredLootSkill() const
Definition CreatureData.h:253
bool IsTameable(bool exotic) const
Definition CreatureData.h:270
uint32 type
Definition GameObjectData.h:33
Definition DBCStructure.h:1024
Definition Map.h:121
bool AllowMount
Definition Map.h:124
uint32 ItemLevel
Definition ItemTemplate.h:635
uint32 LockID
Definition ItemTemplate.h:669
uint32 InventoryType
Definition ItemTemplate.h:632
bool isLooted() const
Definition LootMgr.h:368
Definition DBCStructure.h:1325
bool IsDungeon() const
Definition DBCStructure.h:1351
void GetPosition(float &x, float &y) const
Definition Position.h:126
Definition DBCStructure.h:1817
uint32 flags1
Definition DBCStructure.h:1822
Definition DBCStructure.h:1909
uint32 Category
Definition DBCStructure.h:1911
Definition DBCStructure.h:2064
uint32 m_flags
Definition DBCStructure.h:2066

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, Unit::CastSpell(), SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), SpellInfo::IsTargetingArea(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, sDisableMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SHAPESHIFT_FLAG_STANCE, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_AURA_BOUNCED, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6820{
6821 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6823 return SPELL_CAST_OK;
6824
6825 uint8 school_immune = 0;
6826 uint32 mechanic_immune = 0;
6827 uint32 dispel_immune = 0;
6828
6829 // Check if the spell grants school or mechanic immunity.
6830 // We use bitmasks so the loop is done only once and not on every aura check below.
6832 {
6833 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6834 {
6835 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6836 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6837 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6838 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6839 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6840 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6841 }
6842 // immune movement impairment and loss of control
6843 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6844 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6846 }
6847
6849
6850 // Glyph of Pain Suppression
6851 // there is no other way to handle it
6852 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6853 usableInStun = false;
6854
6855 // Check whether the cast should be prevented by any state you might have.
6856 SpellCastResult prevented_reason = SPELL_CAST_OK;
6857 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6858 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6859
6860 // Xinef: if spell is triggered check preventionType only
6861 if (!preventionOnly)
6862 {
6863 if (unitflag & UNIT_FLAG_STUNNED)
6864 {
6865 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6866 if (usableInStun)
6867 {
6868 bool foundNotStun = false;
6869 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6870 // Barkskin should skip sleep effects, sap and fears
6871 if (m_spellInfo->Id == 22812)
6872 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6873 // Hand of Freedom, can be used while sapped
6874 if (m_spellInfo->Id == 1044)
6875 mask |= 1 << MECHANIC_SAPPED;
6877 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6878 {
6879 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6880 {
6881 foundNotStun = true;
6882 break;
6883 }
6884 }
6885 if (foundNotStun)
6886 prevented_reason = SPELL_FAILED_STUNNED;
6887 }
6888 else
6889 prevented_reason = SPELL_FAILED_STUNNED;
6890 }
6892 prevented_reason = SPELL_FAILED_CONFUSED;
6894 prevented_reason = SPELL_FAILED_FLEEING;
6895 }
6896
6897 // Xinef: if there is no prevented_reason, check prevention types
6898 if (prevented_reason == SPELL_CAST_OK)
6899 {
6901 prevented_reason = SPELL_FAILED_SILENCED;
6903 prevented_reason = SPELL_FAILED_PACIFIED;
6904 }
6905
6906 // Attr must make flag drop spell totally immune from all effects
6907 if (prevented_reason != SPELL_CAST_OK)
6908 {
6909 if (school_immune || mechanic_immune || dispel_immune)
6910 {
6911 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6913 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6914 {
6915 Aura const* aura = itr->second->GetBase();
6916 SpellInfo const* auraInfo = aura->GetSpellInfo();
6917 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6918 continue;
6919 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6920 continue;
6921 if (auraInfo->GetDispelMask() & dispel_immune)
6922 continue;
6923
6924 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6925 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6926 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6927 {
6928 if (AuraEffect* part = aura->GetEffect(i))
6929 {
6930 switch (part->GetAuraType())
6931 {
6933 {
6934 uint32 mask = 1 << MECHANIC_STUN;
6935 // Barkskin should skip sleep effects, sap and fears
6936 if (m_spellInfo->Id == 22812)
6937 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6938 // Hand of Freedom, can be used while sapped
6939 if (m_spellInfo->Id == 1044)
6940 mask |= 1 << MECHANIC_SAPPED;
6941
6942 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6943 return SPELL_FAILED_STUNNED;
6944 break;
6945 }
6948 return SPELL_FAILED_CONFUSED;
6949 break;
6952 return SPELL_FAILED_FLEEING;
6953 break;
6958 return SPELL_FAILED_PACIFIED;
6960 return SPELL_FAILED_SILENCED;
6961 break;
6962 default:
6963 break;
6964 }
6965 }
6966 }
6967 }
6968 }
6969 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6970 else
6971 return prevented_reason;
6972 }
6973 return SPELL_CAST_OK;
6974}
@ SPELL_PREVENTION_TYPE_SILENCE
Definition SharedDefines.h:1565
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1566
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:581
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition SharedDefines.h:595
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition SharedDefines.h:596
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition SharedDefines.h:445
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition SharedDefines.h:446
@ MECHANIC_STUN
Definition SharedDefines.h:1348
@ MECHANIC_FREEZE
Definition SharedDefines.h:1349
@ MECHANIC_SLEEP
Definition SharedDefines.h:1346
@ MECHANIC_SAPPED
Definition SharedDefines.h:1366
@ MECHANIC_HORROR
Definition SharedDefines.h:1360
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition SharedDefines.h:1372
@ SPELL_FAILED_STUNNED
Definition SharedDefines.h:1068
@ SPELL_FAILED_CONFUSED
Definition SharedDefines.h:986
@ SPELL_FAILED_SILENCED
Definition SharedDefines.h:1064
@ SPELL_FAILED_FLEEING
Definition SharedDefines.h:994
@ SPELL_FAILED_PACIFIED
Definition SharedDefines.h:1058
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition SharedDefines.h:617
@ SPELL_AURA_DISPEL_IMMUNITY
Definition SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition UnitDefines.h:272
@ UNIT_FLAG_PACIFIED
Definition UnitDefines.h:271
@ UNIT_FLAG_CONFUSED
Definition UnitDefines.h:276
@ UNIT_FLAG_FLEEING
Definition UnitDefines.h:277
@ UNIT_FLAG_SILENCED
Definition UnitDefines.h:267
Definition SpellAuraEffects.h:39
Definition SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:176
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:1883
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:664
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1368

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:405

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8494{
8495 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8497}
#define ASSERT
Definition Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7917{
7918 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7919 {
7924 if (target->IsCreature() && target->IsVehicle())
7925 return false;
7926 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
7927 return false;
7928 if (target->GetCharmerGUID())
7929 return false;
7930 if (int32 damage = CalculateSpellDamage(eff, target))
7931 if ((int32)target->GetLevel() > damage)
7932 return false;
7933 break;
7934 default:
7935 break;
7936 }
7937
7938 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7939 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7940 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7941 return true;
7942
7943 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7946 {
7947 return true;
7948 }
7949
7951 //Check targets for LOS visibility (except spells without range limitations)
7952 switch (m_spellInfo->Effects[eff].Effect)
7953 {
7955 // player far away, maybe his corpse near?
7956 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7957 {
7959 return false;
7960
7962 if (!corpse)
7963 return false;
7964
7965 if (target->GetGUID() != corpse->GetOwnerGUID())
7966 return false;
7967
7969 return false;
7970 }
7971 break;
7973 {
7975 {
7976 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7977 return true;
7978
7979 return false;
7980 }
7981
7983 if (!corpse)
7984 return false;
7985
7986 if (target->GetGUID() != corpse->GetOwnerGUID())
7987 return false;
7988
7990 return false;
7991
7993 return false;
7994 }
7995 break;
7997 if (!m_caster->IsPlayer() || !target->IsPlayer())
7998 return false;
7999 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8000 return false;
8001 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8002 return false;
8003 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8004 return false;
8005 break;
8006 default: // normal case
8007 {
8008 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8009 GameObject* gobCaster = nullptr;
8011 {
8013 }
8014 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8015 {
8016 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8017 {
8018 gobCaster = tempSummon->GetSummonerGameObject();
8019 }
8020 }
8021
8022 if (gobCaster)
8023 {
8024 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8025 {
8026 return true;
8027 }
8028
8029 // If spell casted by gameobject then ignore M2 models
8030 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8031 }
8032
8033 if (target != m_caster)
8034 {
8035 if (m_targets.HasDst())
8036 {
8037 float x = m_targets.GetDstPos()->GetPositionX();
8038 float y = m_targets.GetDstPos()->GetPositionY();
8039 float z = m_targets.GetDstPos()->GetPositionZ();
8040
8041 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8042 {
8043 return false;
8044 }
8045 }
8047 {
8048 return false;
8049 }
8050 }
8051 break;
8052 }
8053 }
8054
8055 return true;
8056}
@ CORPSE_FLAG_LOOTABLE
Definition Corpse.h:45
@ SPELL_DISABLE_LOS
Definition DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition SharedDefines.h:905
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:115
@ UNIT_FLAG_NOT_SELECTABLE
Definition UnitDefines.h:279
@ CORPSE_FIELD_FLAGS
Definition UpdateFields.h:427
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:201
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:871
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:280
bool IsARecruiter() const
Definition WorldSession.h:608
#define sWorld
Definition World.h:316
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:179
bool IsIgnoringLOSChecks() const
Definition GameObjectData.h:644

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, sDisableMgr, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7157{
7158 Player* player = m_caster->ToPlayer();
7159 if (!player)
7160 {
7161 // Non-player case: Check if creature is disarmed
7163 {
7165 }
7166
7167 return SPELL_CAST_OK;
7168 }
7169
7170 if (!m_CastItem)
7171 {
7172 if (m_castItemGUID)
7174 }
7175 else
7176 {
7177 uint32 itemid = m_CastItem->GetEntry();
7178 if (!player->HasItemCount(itemid))
7180
7181 ItemTemplate const* proto = m_CastItem->GetTemplate();
7182 if (!proto)
7184
7185 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7186 if (proto->Spells[i].SpellCharges)
7187 if (m_CastItem->GetSpellCharges(i) == 0)
7189
7190 // consumable cast item checks
7192 {
7193 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7194 SpellCastResult failReason = SPELL_CAST_OK;
7195 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7196 {
7197 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7198 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7199 continue;
7200
7201 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7202 {
7204 {
7206 continue;
7207 }
7208 else
7209 {
7210 failReason = SPELL_CAST_OK;
7211 break;
7212 }
7213 }
7214
7215 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7216 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7217 {
7218 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7219 {
7221 continue;
7222 }
7223
7224 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7226 {
7228 continue;
7229 }
7230 else
7231 {
7232 failReason = SPELL_CAST_OK;
7233 break;
7234 }
7235 }
7236 }
7237 if (failReason != SPELL_CAST_OK)
7238 return failReason;
7239 }
7240 }
7241
7242 // check target item
7244 {
7245 if (!m_caster->IsPlayer())
7247
7248 if (!m_targets.GetItemTarget())
7250
7253 }
7254 // if not item target then required item must be equipped
7255 else
7256 {
7257 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7258 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7261 }
7262
7263 // do not take reagents for these item casts
7265 {
7267 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7268 if (!checkReagents)
7269 if (Item* targetItem = m_targets.GetItemTarget())
7270 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7271 checkReagents = true;
7272
7273 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7274 if (checkReagents)
7275 {
7276 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7277 {
7278 if (m_spellInfo->Reagent[i] <= 0)
7279 continue;
7280
7281 uint32 itemid = m_spellInfo->Reagent[i];
7282 uint32 itemcount = m_spellInfo->ReagentCount[i];
7283
7284 // if CastItem is also spell reagent
7285 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7286 {
7287 ItemTemplate const* proto = m_CastItem->GetTemplate();
7288 if (!proto)
7290 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7291 {
7292 // CastItem will be used up and does not count as reagent
7293 int32 charges = m_CastItem->GetSpellCharges(s);
7294 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7295 {
7296 ++itemcount;
7297 break;
7298 }
7299 }
7300 }
7301 if (!player->HasItemCount(itemid, itemcount))
7302 return SPELL_FAILED_REAGENTS;
7303 }
7304 }
7305
7306 // check totem-item requirements (items presence in inventory)
7307 uint32 totems = 2;
7308 for (int i = 0; i < 2; ++i)
7309 {
7310 if (m_spellInfo->Totem[i] != 0)
7311 {
7312 if (player->HasItemCount(m_spellInfo->Totem[i]))
7313 {
7314 totems -= 1;
7315 continue;
7316 }
7317 }
7318 else
7319 totems -= 1;
7320 }
7321 if (totems != 0)
7322 return SPELL_FAILED_TOTEMS; //0x7C
7323
7324 // Check items for TotemCategory (items presence in inventory)
7326 for (int i = 0; i < 2; ++i)
7327 {
7328 if (m_spellInfo->TotemCategory[i] != 0)
7329 {
7331 {
7332 TotemCategory -= 1;
7333 continue;
7334 }
7335 }
7336 else
7337 TotemCategory -= 1;
7338 }
7339 if (TotemCategory != 0)
7340 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7341 }
7342
7343 // special checks for spell effects
7344 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7345 {
7346 switch (m_spellInfo->Effects[i].Effect)
7347 {
7350 {
7351 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7352 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7353 if (target->IsPlayer() && !IsTriggered())
7354 {
7355 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7356 // so we need to make sure there is at least one free space in the player's inventory
7358 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7359 {
7360 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7362 }
7363
7364 if (m_spellInfo->Effects[i].ItemType)
7365 {
7366 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7367 if (!itemTemplate)
7369
7370 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7371 ItemPosCountVec dest;
7372 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7373 if (msg != EQUIP_ERR_OK)
7374 {
7376 if (!itemTemplate->ItemLimitCategory)
7377 {
7378 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7380 }
7381 else
7382 {
7383 // Conjure Food/Water/Refreshment spells
7386 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7387 {
7388 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7390 }
7391 else
7392 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7393
7395 }
7396 }
7397 }
7398 }
7399 break;
7400 }
7402 {
7403 if (player->GetFreeInventorySpace() == 0)
7404 {
7405 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7407 }
7408 break;
7409 }
7411 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7413 {
7414 // cannot enchant vellum for other player
7417 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7420 ItemPosCountVec dest;
7421 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7422 if (msg != EQUIP_ERR_OK)
7423 {
7424 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7426 }
7427 }
7428 [[fallthrough]];
7430 {
7431 Item* targetItem = m_targets.GetItemTarget();
7432 if (!targetItem)
7434
7435 // Apply item level restriction
7437 {
7438 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7439 if (!requiredLevel)
7440 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7441
7442 if (requiredLevel < m_spellInfo->BaseLevel)
7443 return SPELL_FAILED_LOWLEVEL;
7444 }
7445
7446 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7448
7449 bool isItemUsable = false;
7450 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7451 {
7452 ItemTemplate const* proto = targetItem->GetTemplate();
7453 if (proto->Spells[e].SpellId && (
7456 {
7457 isItemUsable = true;
7458 break;
7459 }
7460 }
7461
7462 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7463 // do not allow adding usable enchantments to items that have use effect already
7464 if (enchantEntry)
7465 {
7466 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7467 {
7468 switch (enchantEntry->type[s])
7469 {
7471 if (isItemUsable)
7473 break;
7475 {
7476 uint32 numSockets = 0;
7477 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7478 if (targetItem->GetTemplate()->Socket[socket].Color)
7479 ++numSockets;
7480
7481 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7483 break;
7484 }
7485 }
7486 }
7487 }
7488
7489 // Not allow enchant in trade slot for some enchant type
7490 if (targetItem->GetOwner() != m_caster)
7491 {
7492 if (!enchantEntry)
7493 return SPELL_FAILED_ERROR;
7494 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7496 }
7497 break;
7498 }
7500 {
7501 Item* item = m_targets.GetItemTarget();
7502 if (!item)
7504 // Not allow enchant in trade slot for some enchant type
7505 if (item->GetOwner() != m_caster)
7506 {
7507 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7508 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7509 if (!pEnchant)
7510 return SPELL_FAILED_ERROR;
7511 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7513 }
7514
7515 // Apply item level restriction
7517 {
7518 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7519 if (!requiredLevel)
7520 requiredLevel = item->GetTemplate()->ItemLevel;
7521
7522 if (requiredLevel < m_spellInfo->BaseLevel)
7523 return SPELL_FAILED_LOWLEVEL;
7524 }
7525
7528
7529 break;
7530 }
7532 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7533 break;
7535 {
7536 if (!m_targets.GetItemTarget())
7538
7539 // prevent disenchanting in trade slot
7542
7543 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7544 if (!itemProto)
7546
7547 uint32 item_quality = itemProto->Quality;
7548 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7549 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7550 if (item_disenchantskilllevel == uint32(-1))
7552 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7554 if (item_quality > 4 || item_quality < 2)
7556 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7558 if (!itemProto->DisenchantID)
7560 break;
7561 }
7563 {
7564 if (!m_targets.GetItemTarget())
7566 //ensure item is a prospectable ore
7569 //prevent prospecting in trade slot
7572 //Check for enough skill in jewelcrafting
7573 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7574 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7576 //make sure the player has the required ores in inventory
7577 if (m_targets.GetItemTarget()->GetCount() < 5)
7579
7582
7583 break;
7584 }
7586 {
7587 if (!m_targets.GetItemTarget())
7589 //ensure item is a millable herb
7592 //prevent milling in trade slot
7595 //Check for enough skill in inscription
7596 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7597 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7599 //make sure the player has the required herbs in inventory
7600 if (m_targets.GetItemTarget()->GetCount() < 5)
7602
7605
7606 break;
7607 }
7610 {
7611 if (!m_caster->IsPlayer())
7613
7615 break;
7616
7618 if (!pItem || pItem->IsBroken())
7620
7621 switch (pItem->GetTemplate()->SubClass)
7622 {
7624 {
7625 uint32 ammo = pItem->GetEntry();
7626 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7627 return SPELL_FAILED_NO_AMMO;
7628 };
7629 break;
7633 {
7635 if (!ammo)
7636 {
7637 // Requires No Ammo
7638 if (m_caster->HasAura(46699))
7639 break; // skip other checks
7640
7641 return SPELL_FAILED_NO_AMMO;
7642 }
7643
7644 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7645 if (!ammoProto)
7646 return SPELL_FAILED_NO_AMMO;
7647
7648 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7649 return SPELL_FAILED_NO_AMMO;
7650
7651 // check ammo ws. weapon compatibility
7652 switch (pItem->GetTemplate()->SubClass)
7653 {
7656 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7657 return SPELL_FAILED_NO_AMMO;
7658 break;
7660 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7661 return SPELL_FAILED_NO_AMMO;
7662 break;
7663 default:
7664 return SPELL_FAILED_NO_AMMO;
7665 }
7666
7667 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7668 {
7670 return SPELL_FAILED_NO_AMMO;
7671 }
7672 };
7673 break;
7675 break;
7676 default:
7677 break;
7678 }
7679 break;
7680 }
7682 {
7683 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7684 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7685
7686 if (!pProto)
7688
7689 if (Item* pitem = player->GetItemByEntry(item_id))
7690 {
7691 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7692 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7694 }
7695 break;
7696 }
7697 default:
7698 break;
7699 }
7700 }
7701
7702 // check weapon presence in slots for main/offhand weapons
7703 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7704 {
7705 // main hand weapon required
7707 {
7709
7710 // skip spell if no weapon in slot or broken
7711 if (!item || item->IsBroken())
7713
7714 // skip spell if weapon not fit to triggered spell
7717 }
7718
7719 // offhand hand weapon required
7721 {
7723
7724 // skip spell if no weapon in slot or broken
7725 if (!item || item->IsBroken())
7727
7728 // skip spell if weapon not fit to triggered spell
7731 }
7732
7734 }
7735
7736 return SPELL_CAST_OK;
7737}
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:374
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_SPELL_REAGENTS
Definition DBCStructure.h:1639
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1838
std::int8_t int8
Definition Define.h:105
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition ItemTemplate.h:291
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_OK
Definition Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition Item.h:97
#define MAX_ITEM_SPELLS
Definition Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition Item.h:201
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition Item.h:175
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:758
@ EFFECT_1
Definition SharedDefines.h:32
@ MAX_POWERS
Definition SharedDefines.h:287
@ SPELL_EFFECT_DISENCHANT
Definition SharedDefines.h:888
@ SPELL_EFFECT_PROSPECTING
Definition SharedDefines.h:916
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:881
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:842
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:847
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:799
@ SPELL_EFFECT_MILLING
Definition SharedDefines.h:947
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition SharedDefines.h:855
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:946
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:806
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:819
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition SharedDefines.h:848
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:945
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:843
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:813
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
Definition SharedDefines.h:470
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition SharedDefines.h:514
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3787
TotemCategory
Definition SharedDefines.h:3323
@ SPELL_FAILED_CANT_BE_MILLED
Definition SharedDefines.h:976
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition SharedDefines.h:991
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition SharedDefines.h:989
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition SharedDefines.h:1139
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition SharedDefines.h:1082
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition SharedDefines.h:964
@ SPELL_FAILED_NOT_TRADEABLE
Definition SharedDefines.h:1030
@ SPELL_FAILED_ITEM_NOT_READY
Definition SharedDefines.h:1005
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition SharedDefines.h:1036
@ SPELL_FAILED_ITEM_GONE
Definition SharedDefines.h:1003
@ SPELL_FAILED_NO_AMMO
Definition SharedDefines.h:1035
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition SharedDefines.h:1004
@ SPELL_FAILED_EQUIPPED_ITEM
Definition SharedDefines.h:988
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition SharedDefines.h:962
@ SPELL_FAILED_ON_USE_ENCHANT
Definition SharedDefines.h:1130
@ SPELL_FAILED_TOTEMS
Definition SharedDefines.h:1091
@ SPELL_FAILED_ERROR
Definition SharedDefines.h:992
@ SPELL_FAILED_REAGENTS
Definition SharedDefines.h:1060
@ SPELL_FAILED_MAX_SOCKETS
Definition SharedDefines.h:1144
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition SharedDefines.h:974
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition SharedDefines.h:1089
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition SharedDefines.h:1015
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition SharedDefines.h:977
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition SharedDefines.h:990
@ SPELL_FAILED_TOTEM_CATEGORY
Definition SharedDefines.h:1090
@ SKILL_INSCRIPTION
Definition SharedDefines.h:3242
@ SKILL_ENCHANTING
Definition SharedDefines.h:3194
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3225
@ PLAYER_AMMO_ID
Definition UpdateFields.h:369
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:317
bool IsBroken() const
Definition Item.h:257
bool IsWeaponVellum() const
Definition Item.h:338
bool IsArmorVellum() const
Definition Item.h:339
Player * GetOwner() const
Definition Item.cpp:549
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
uint32 GetCount() const
Definition Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:884
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:224
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:294
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12530
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:468
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3430
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:657
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:858
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12575
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4088
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1298
uint32 GetItemTargetEntry() const
Definition Spell.h:150
uint32 MaxLevel
Definition SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition SpellInfo.h:373
flag96 SpellFamilyFlags
Definition SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition SpellInfo.h:378
int32 EquippedItemClass
Definition SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition SpellInfo.h:374
ObjectGuid m_castItemGUID
Definition Spell.h:534
bool IsFullHealth() const
Definition Unit.h:1099
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:977
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1121
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:21425
uint32 GetPower(Powers power) const
Definition Unit.h:1120
Definition ItemTemplate.h:619
uint32 DisenchantID
Definition ItemTemplate.h:690
uint32 Quality
Definition ItemTemplate.h:626
uint32 RequiredSkillRank
Definition ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition ItemTemplate.h:727
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition ItemTemplate.h:684
uint32 RequiredLevel
Definition ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:825
uint32 Class
Definition ItemTemplate.h:621
uint32 ItemLimitCategory
Definition ItemTemplate.h:687
uint32 SubClass
Definition ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition ItemTemplate.h:681
Definition DBCStructure.h:1841
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1844
uint32 slot
Definition DBCStructure.h:1851
uint32 Color
Definition ItemTemplate.h:602
int32 SpellCharges
Definition ItemTemplate.h:593
uint32 SpellTrigger
Definition ItemTemplate.h:592
int32 SpellId
Definition ItemTemplate.h:591

References BASE_ATTACK, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6784{
6785 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6787
6788 // dead owner (pets still alive when owners ressed?)
6789 if (Unit* owner = m_caster->GetCharmerOrOwner())
6790 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6792
6793 if (!target && m_targets.GetUnitTarget())
6794 target = m_targets.GetUnitTarget();
6795
6797 {
6798 if (!target)
6800 m_targets.SetUnitTarget(target);
6801 }
6802
6803 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6805
6806 // cooldown
6807 if (Creature const* creatureCaster = m_caster->ToCreature())
6808 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6810
6811 // Check if spell is affected by GCD
6815
6816 return CheckCast(true);
6817}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition Spell.cpp:238
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2297
uint32 StartRecoveryCategory
Definition SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7112{
7113 // item cast not used power
7114 if (m_CastItem)
7115 return SPELL_CAST_OK;
7116
7117 //While .cheat power is enabled dont check if we need power to cast the spell
7118 if (m_caster->IsPlayer())
7119 {
7121 {
7122 return SPELL_CAST_OK;
7123 }
7124 }
7125
7126 // health as power used - need check health amount
7128 {
7131 return SPELL_CAST_OK;
7132 }
7133 // Check valid power type
7135 {
7136 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7137 return SPELL_FAILED_UNKNOWN;
7138 }
7139
7140 //check rune cost only if a spell has PowerType == POWER_RUNE
7142 {
7144 if (failReason != SPELL_CAST_OK)
7145 return failReason;
7146 }
7147
7148 // Check power amount
7151 return SPELL_FAILED_NO_POWER;
7152 else
7153 return SPELL_CAST_OK;
7154}
@ CHEAT_POWER
Definition Player.h:999
@ POWER_HEALTH
Definition SharedDefines.h:289
@ POWER_RUNE
Definition SharedDefines.h:285
@ SPELL_FAILED_NO_POWER
Definition SharedDefines.h:1045
@ SPELL_FAILED_UNKNOWN
Definition SharedDefines.h:1147
PowerType
Definition VehicleDefines.h:29
uint32 RuneCostID
Definition SpellInfo.h:368
uint32 PowerType
Definition SpellInfo.h:362
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition Spell.cpp:5358
uint32 GetHealth() const
Definition Unit.h:1093

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7026{
7027 // Don't check for instant cast spells
7028 if (!strict && m_casttime == 0)
7029 return SPELL_CAST_OK;
7030
7031 uint32 range_type = 0;
7032
7034 {
7035 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7036 // these are triggered by other spells - possibly we should omit range check in that case?
7037 if (m_spellInfo->RangeEntry->ID == 1)
7038 return SPELL_CAST_OK;
7039
7040 range_type = m_spellInfo->RangeEntry->Flags;
7041 }
7042
7043 Unit* target = m_targets.GetUnitTarget();
7044 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7045 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7046
7047 // xinef: hack for npc shooters
7048 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7049 range_type = SPELL_RANGE_RANGED;
7050
7051 if (Player* modOwner = m_caster->GetSpellModOwner())
7052 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7053
7054 // xinef: dont check max_range to strictly after cast
7055 if (range_type != SPELL_RANGE_MELEE && !strict)
7056 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7057
7058 if (target)
7059 {
7060 if (target != m_caster)
7061 {
7062 // Xinef: Spells with 5yd range can hit target 9yd away?
7063 if (range_type == SPELL_RANGE_MELEE)
7064 {
7065 float real_max_range = max_range;
7067 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7068 else
7069 real_max_range -= 2 * MIN_MELEE_REACH;
7070
7071 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7073 }
7074 else if (!m_caster->IsWithinCombatRange(target, max_range))
7075 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7076
7078 {
7079 if (m_caster->IsWithinMeleeRange(target))
7081 }
7082
7083 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7085 }
7086
7087 // Xinef: check min range for self casts
7088 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7090 }
7091
7092 if (GameObject* goTarget = m_targets.GetGOTarget())
7093 {
7094 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7095 {
7097 }
7098 }
7099
7100 if (m_targets.HasDst() && !m_targets.HasTraj())
7101 {
7102 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7104 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7106 }
7107
7108 return SPELL_CAST_OK;
7109}
#define MIN_MELEE_REACH
Definition ObjectDefines.h:46
@ SPELL_FAILED_TOO_CLOSE
Definition SharedDefines.h:1088
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1057
@ SPELLMOD_RANGE
Definition SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition SpellDefines.h:128
@ SPELL_RANGE_MELEE
Definition Spell.h:92
@ SPELL_RANGE_RANGED
Definition Spell.h:93
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:369
uint32 FacingCasterFlags
Definition SpellInfo.h:338
bool IsWithinBoundaryRadius(const Unit *obj) const
Definition Unit.cpp:704
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:649
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15281
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:665
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15261
bool HasLeewayMovement() const
Definition Unit.h:1709
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1321
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition Position.cpp:148
uint32 Flags
Definition DBCStructure.h:1797
uint32 ID
Definition DBCStructure.h:1794

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), Unit::HasLeewayMovement(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Object::IsPlayer(), Unit::IsWithinBoundaryRadius(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5359{
5360 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5361 return SPELL_CAST_OK;
5362
5363 if (!m_caster->IsPlayer())
5364 return SPELL_CAST_OK;
5365
5366 Player* player = m_caster->ToPlayer();
5367 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5368 if (player->GetCommandStatus(CHEAT_POWER))
5369 {
5370 return SPELL_CAST_OK;
5371 }
5372
5374 return SPELL_CAST_OK;
5375
5376 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5377
5378 if (!src)
5379 return SPELL_CAST_OK;
5380
5381 if (src->NoRuneCost())
5382 return SPELL_CAST_OK;
5383
5384 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5385
5386 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5387 {
5388 runeCost[i] = src->RuneCost[i];
5389 if (Player* modOwner = m_caster->GetSpellModOwner())
5390 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5391 }
5392
5393 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5394
5395 for (uint32 i = 0; i < MAX_RUNES; ++i)
5396 {
5397 RuneType rune = player->GetCurrentRune(i);
5398 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5399 runeCost[rune]--;
5400 }
5401
5402 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5403 if (runeCost[i] > 0)
5404 runeCost[RUNE_DEATH] += runeCost[i];
5405
5406 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5407 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5408
5409 return SPELL_CAST_OK;
5410}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition Player.h:396
@ RUNE_DEATH
Definition Player.h:400
@ NUM_RUNE_TYPES
Definition Player.h:401
#define MAX_RUNES
Definition Player.h:386
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:146
@ SPELLMOD_COST
Definition SpellDefines.h:90
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:238
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2541
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1302
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2540
Definition DBCStructure.h:1805
uint32 RuneCost[3]
Definition DBCStructure.h:1807
bool NoRuneCost() const
Definition DBCStructure.h:1810

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8715{
8716 // Skip if there are not any script
8717 if (!m_loadedScripts.size())
8718 return true;
8719
8720 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8721 {
8722 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8723 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8724 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8725 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8726 return false;
8727
8728 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8729 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8730 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8731 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8732 return false;
8733 }
8734 return true;
8735}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7740{
7741 // check spell focus object
7743 {
7745 Cell cell(p);
7746
7747 GameObject* ok = nullptr;
7750
7752 Map& map = *m_caster->GetMap();
7753 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7754
7755 if (!ok)
7757
7758 focusObject = ok; // game object found in range
7759 }
7760 return SPELL_CAST_OK;
7761}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1062
Definition GridNotifiers.h:648
Definition Map.h:163
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:701
uint32 RequiresSpellFocus
Definition SpellInfo.h:337
Definition TypeContainerVisitor.h:105
Definition TypeContainer.h:118
CellCoord ComputeCellCoord(float x, float y)
Definition GridDefines.h:197
Definition GridNotifiers.h:310
Definition Cell.h:45

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition Spell.h:174
void SetSrc(float x, float y, float z)
Definition Spell.cpp:366

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2276{
2277 m_UniqueTargetInfo.clear();
2278 m_UniqueGOTargetInfo.clear();
2279 m_UniqueItemInfo.clear();
2280 m_delayMoment = 0;
2282}
uint64 m_delayTrajectory
Definition Spell.h:652

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7764{
7765 if (!m_caster)// || !m_caster->IsPlayer())
7766 return;
7767
7768 //if (m_spellState == SPELL_STATE_DELAYED)
7769 // return; // spell is active and can't be time-backed
7770
7771 if (isDelayableNoMore()) // Spells may only be delayed twice
7772 return;
7773
7775 return;
7776
7777 // spells not loosing casting time (slam, dynamites, bombs..)
7778 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7779 // return;
7780
7781 //check pushback reduce
7782 int32 delaytime = 500; // spellcasting delay is normally 500ms
7783 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7786 if (delayReduce >= 100)
7787 return;
7788
7789 AddPct(delaytime, -delayReduce);
7790
7791 if (m_timer + delaytime > m_casttime)
7792 {
7793 delaytime = m_casttime - m_timer;
7795 }
7796 else
7797 m_timer += delaytime;
7798
7799 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7800
7801 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7802 data << m_caster->GetPackGUID();
7803 data << uint32(delaytime);
7804
7805 m_caster->SendMessageToSet(&data, true);
7806}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ SPELL_ATTR6_NO_PUSHBACK
Definition SharedDefines.h:630
@ SPELL_AURA_REDUCE_PUSHBACK
Definition SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition SpellDefines.h:85
T AddPct(T &base, U pct)
Definition Util.h:58
PackedGuid const & GetPackGUID() const
Definition Object.h:115
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:9760
bool isDelayableNoMore()
Definition Spell.h:640
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6133
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2083
Definition WorldPacket.h:26
@ SMSG_SPELL_DELAYED
Definition Opcodes.h:512

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7809{
7811 return;
7812
7813 if (isDelayableNoMore()) // Spells may only be delayed twice
7814 return;
7815
7817 return;
7818
7819 //check pushback reduce
7820 // should be affected by modifiers, not take the dbc duration.
7821 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7822
7823 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7824 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7827 if (delayReduce >= 100)
7828 return;
7829
7830 AddPct(delaytime, -delayReduce);
7831
7832 if (m_timer <= delaytime)
7833 {
7834 delaytime = m_timer;
7835 m_timer = 0;
7836 }
7837 else
7838 m_timer -= delaytime;
7839
7840 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7841
7842 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7843 if ((*ihit).missCondition == SPELL_MISS_NONE)
7844 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7845 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7846
7847 // partially interrupt persistent area auras
7849 dynObj->Delay(delaytime);
7850
7852}
T CalculatePct(T base, U pct)
Definition Util.h:52
Definition DynamicObject.h:35
uint32 getState() const
Definition Spell.h:493
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6362

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8292{
8293 Unit* unit = nullptr;
8294 // In case spell hit target, do all effect on that target
8295 if (targetInfo.missCondition == SPELL_MISS_NONE)
8296 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8297 // In case spell reflect from target, do all effect on caster (if hit)
8298 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8299 unit = m_caster;
8300 if (!unit)
8301 return;
8302
8303 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8304 {
8305 if (targetInfo.effectMask & (1 << i))
8306 {
8307 m_damage = 0;
8308 m_healing = 0;
8309
8310 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8311
8312 if (m_damage > 0)
8313 {
8314 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8315 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8316 {
8319 if (m_caster->IsPlayer())
8320 {
8321 uint32 targetAmount = m_UniqueTargetInfo.size();
8322 if (targetAmount > 10)
8323 m_damage = m_damage * 10 / targetAmount;
8324 }
8325 }
8326 }
8327
8328 if (m_applyMultiplierMask & (1 << i))
8329 {
8331 m_damageMultipliers[i] *= multiplier[i];
8332 }
8333 targetInfo.damage += m_damage;
8334 }
8335 }
8336
8337 // xinef: totem's inherit owner crit chance and dancing rune weapon
8338 Unit* caster = m_caster;
8339 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8340 {
8341 if (Unit* owner = m_caster->GetOwner())
8342 caster = owner;
8343 }
8344 else if (m_originalCaster)
8345 caster = m_originalCaster;
8346
8347 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8348 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8349 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8350}
bool roll_chance_f(float chance)
Definition Random.h:57
@ SPELL_ATTR7_TREAT_AS_NPC_AOE
Definition SharedDefines.h:678
uint32 SchoolMask
Definition SpellInfo.h:392
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12265
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12190
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:20380

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), GetSpellInfo(), ObjectAccessor::GetUnit(), HandleEffects(), SpellInfo::HasAttribute(), Unit::IsControlledByPlayer(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_ATTR7_TREAT_AS_NPC_AOE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3269{
3270 if (target->processed) // Check target
3271 return;
3272 target->processed = true; // Target checked in apply effects procedure
3273
3274 uint32 effectMask = target->effectMask;
3275 if (!effectMask)
3276 return;
3277
3278 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3279 if (!go)
3280 return;
3281
3284
3285 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3286 if (effectMask & (1 << effectNumber))
3287 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3288
3289 // xinef: inform ai about spellhit
3291
3293
3295}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:305
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8633
void CallScriptOnHitHandlers()
Definition Spell.cpp:8646
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8659

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3298{
3299 uint32 effectMask = target->effectMask;
3300 if (!target->item || !effectMask)
3301 return;
3302
3305
3306 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3307 if (effectMask & (1 << effectNumber))
3308 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3309
3311
3313}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2514{
2515 if (!target || target->processed)
2516 return;
2517
2518 target->processed = true; // Target checked in apply effects procedure
2519
2520 // Get mask of effects for target
2521 uint8 mask = target->effectMask;
2522
2523 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2524 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2525 return;
2526
2527 if (!effectUnit || m_spellInfo->Id == 45927)
2528 {
2529 uint8 farMask = 0;
2530 // create far target mask
2531 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2532 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2533 if ((1 << i) & mask)
2534 farMask |= (1 << i);
2535
2536 if (!farMask)
2537 return;
2538 // find unit in world
2539 // Xinef: FindUnit Access without Map check!!! Intended
2540 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2541 if (!effectUnit)
2542 return;
2543
2544 // do far effects on the unit
2545 // can't use default call because of threading, do stuff as fast as possible
2546 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2547 if (farMask & (1 << i))
2548 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2549 return;
2550 }
2551
2552 if (effectUnit->IsAlive() != target->alive)
2553 return;
2554
2555 // Xinef: absorb delayed projectiles for 500ms
2557 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2558 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2559 )
2560 return; // No missinfo in that case
2561
2562 // Get original caster (if exist) and calculate damage/healing from him data
2564
2565 // Skip if m_originalCaster not avaiable
2566 if (!caster)
2567 return;
2568
2569 SpellMissInfo missInfo = target->missCondition;
2570
2571 // Need init unitTarget by default unit (can changed in code on reflect)
2572 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2573 unitTarget = effectUnit;
2574
2575 // Reset damage/healing counter
2576 m_damage = target->damage;
2577 m_healing = -target->damage;
2578
2579 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2580
2583
2584 //Spells with this flag cannot trigger if effect is casted on self
2586 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2587 Unit* reflectionSource = nullptr;
2588 Unit* spellHitTarget = nullptr;
2589
2590 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2591 spellHitTarget = unitTarget;
2592 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2593 {
2594 missInfo = target->reflectResult;
2595 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2596 {
2597 spellHitTarget = m_caster;
2599 reflectionSource = effectUnit;
2600 if (m_caster->IsCreature())
2602 }
2603 }
2604
2605 if (spellHitTarget)
2606 {
2607 if (reflectionSource)
2608 {
2609 m_reflectionTarget = reflectionSource;
2610 m_reflectionTargetGuid = reflectionSource->GetGUID();
2611 m_reflectionTargetPosition.Relocate(reflectionSource);
2612 }
2613 else
2614 {
2615 m_reflectionTarget = nullptr;
2618 }
2619
2620 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2621
2622 m_reflectionTarget = nullptr;
2625 if (missInfo2 != SPELL_MISS_NONE)
2626 {
2627 if (missInfo2 != SPELL_MISS_MISS)
2628 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2629 m_damage = 0;
2630 spellHitTarget = nullptr;
2631
2632 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2633 if (missInfo2 == SPELL_MISS_EVADE)
2634 missInfo = SPELL_MISS_EVADE;
2635 }
2636 }
2637
2638 // Do not take combo points on dodge and miss
2639 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2640 {
2641 m_needComboPoints = false;
2642 // Restore spell mods for a miss/dodge/parry Cold Blood
2644 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2645 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2646 }
2647
2648 // Fill base trigger info
2649 uint32 procAttacker = m_procAttacker;
2650 uint32 procVictim = m_procVictim;
2651 uint32 procEx = m_procEx;
2652
2653 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2654 if (canEffectTrigger && !procAttacker && !procVictim)
2655 {
2656 bool positive = true;
2657 if (m_damage > 0)
2658 positive = false;
2659 else if (!m_healing)
2660 {
2661 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2662 // If at least one effect negative spell is negative hit
2663 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2664 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2665 {
2666 positive = false;
2667 break;
2668 }
2669 }
2670 switch (m_spellInfo->DmgClass)
2671 {
2673 if (positive)
2674 {
2677 }
2678 else
2679 {
2682 }
2683 break;
2685 if (positive)
2686 {
2689 }
2690 else
2691 {
2694 }
2695 break;
2696 }
2697 }
2699
2700 // All calculated do it!
2701 // Do healing and triggers
2702 if (m_healing > 0)
2703 {
2704 bool crit = target->crit;
2705 uint32 addhealth = m_healing;
2706
2707 if (crit)
2708 {
2709 procEx |= PROC_EX_CRITICAL_HIT;
2710 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2711 }
2712 else
2713 procEx |= PROC_EX_NORMAL_HIT;
2714
2715 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2716
2717 // Xinef: override with forced crit, only visual result
2718 if (GetSpellValue()->ForcedCritResult)
2719 {
2720 crit = true;
2721 procEx |= PROC_EX_CRITICAL_HIT;
2722 }
2723
2724 int32 gain = caster->HealBySpell(healInfo, crit);
2725 float threat = float(gain) * 0.5f;
2726 if (caster->IsClass(CLASS_PALADIN))
2727 threat *= 0.5f;
2728
2730 m_healing = gain;
2731
2732 // Xinef: if heal acutally healed something, add no overheal flag
2733 if (m_healing)
2734 procEx |= PROC_EX_NO_OVERHEAL;
2735
2736 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2737 if (canEffectTrigger)
2738 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2739 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2740 }
2741 // Do damage and triggers
2742 else if (m_damage > 0)
2743 {
2745
2746 // Fill base damage struct (unitTarget - is real spell target)
2748
2749 // Add bonuses and fill damageInfo struct
2750 // Dancing Rune Weapon...
2751 if (m_caster->GetEntry() == 27893)
2752 {
2753 if (Unit* owner = m_caster->GetOwner())
2754 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2755 }
2756 else
2757 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2758
2759 // xinef: override miss info after absorb / block calculations
2760 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2761 {
2762 //if (damageInfo.absorb > 0)
2763 // missInfo = SPELL_MISS_ABSORB;
2764 if (damageInfo.blocked)
2765 missInfo = SPELL_MISS_BLOCK;
2766 }
2767
2768 // Xinef: override with forced crit, only visual result
2769 if (GetSpellValue()->ForcedCritResult)
2770 {
2771 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2772 }
2773
2774 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2775
2776 // xinef: health leech handling
2778 {
2779 uint8 effIndex = EFFECT_0;
2780 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2781 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2782 break;
2783
2784 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2785
2786 // get max possible damage, don't count overkill for heal
2787 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2788
2789 if (m_caster->IsAlive())
2790 {
2791 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2792 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2793
2794 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2795 m_caster->HealBySpell(healInfo);
2796 }
2797 }
2798
2799 // Send log damage message to client
2800 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2801 // Xinef: send info to target about reflect
2802 if (reflectedSpell)
2803 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2804
2805 procEx |= createProcExtendMask(&damageInfo, missInfo);
2806 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2807
2808 caster->DealSpellDamage(&damageInfo, true, this);
2809
2810 // do procs after damage, eg healing effects
2811 // no need to check if target is alive, done in procdamageandspell
2812
2813 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2814 if (canEffectTrigger)
2815 {
2816 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2817 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2818 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2819
2822 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2823 }
2824
2825 m_damage = damageInfo.damage;
2826 }
2827 // Passive spell hits/misses or active spells only misses (only triggers)
2828 else
2829 {
2830 // Fill base damage struct (unitTarget - is real spell target)
2832 procEx |= createProcExtendMask(&damageInfo, missInfo);
2833 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2834 if (canEffectTrigger)
2835 {
2836 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2837 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2838 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2839
2840 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2841 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2845 }
2846
2847 // Failed Pickpocket, reveal rogue
2849 {
2853 }
2854 }
2855
2856 if (m_caster)
2857 {
2859 {
2862
2863 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2864 if (effectUnit->IsInCombatWith(m_caster))
2865 {
2866 if (Creature* creature = effectUnit->ToCreature())
2867 {
2868 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2869 {
2870 creature->SetLootRecipient(m_caster);
2871 }
2872 }
2873 }
2874
2875 // Unsure if there are more spells that are not supposed to stop enemy from
2876 // regenerating HP from food, so for now it stays as an ID.
2877 const uint32 SPELL_PREMEDITATION = 14183;
2878 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2879 {
2880 if (!effectUnit->IsStandState())
2881 {
2883 }
2884 }
2885 }
2886 }
2887
2888 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2890 {
2891 m_caster->SetInCombatWith(effectUnit);
2892 }
2893
2894 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2896 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2897
2898 if (spellHitTarget)
2899 {
2900 //AI functions
2901 if (spellHitTarget->IsCreature())
2902 {
2903 if (spellHitTarget->ToCreature()->IsAIEnabled)
2904 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2905 }
2906
2908 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2909
2910 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2911 DoTriggersOnSpellHit(spellHitTarget, mask);
2912
2913 // if target is fallged for pvp also flag caster if a player
2914 // xinef: do not flag spells with aura bind sight (no special attribute)
2915 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2917 {
2918 m_caster->ToPlayer()->UpdatePvP(true);
2919 }
2920
2922 }
2923}
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:798
@ SPELL_ATTR1_NO_THREAT
Definition SharedDefines.h:440
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition SharedDefines.h:520
@ CLASS_PALADIN
Definition SharedDefines.h:142
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition SharedDefines.h:413
@ SPELL_HIT_TYPE_CRIT
Definition SharedDefines.h:1547
SpellMissInfo
Definition SharedDefines.h:1529
@ SPELL_MISS_DODGE
Definition SharedDefines.h:1533
@ SPELL_MISS_IMMUNE2
Definition SharedDefines.h:1538
@ SPELL_MISS_RESIST
Definition SharedDefines.h:1532
@ SPELL_MISS_MISS
Definition SharedDefines.h:1531
@ SPELL_MISS_BLOCK
Definition SharedDefines.h:1535
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition SharedDefines.h:564
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:53
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:186
@ PROC_EX_NO_OVERHEAL
Definition SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:123
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition Spell.h:278
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:32
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition Unit.cpp:16224
@ NODAMAGE
Definition Unit.h:259
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:256
@ HEAL
Definition Unit.h:258
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition CreatureAI.h:148
virtual void SpellHit(Unit *, SpellInfo const *)
Definition CreatureAI.h:145
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition Creature.cpp:3680
CreatureAI * AI() const
Definition Creature.h:144
Definition Unit.h:337
Definition Unit.h:380
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition HostileRefMgr.cpp:35
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:9902
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7230
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1532
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:215
uint32 AttributesEx3
Definition SpellInfo.h:327
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition SpellInfo.cpp:1582
bool IsPositiveEffect(uint8 effIndex) const
Definition SpellInfo.cpp:1242
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition Spell.cpp:8737
SpellValue const * GetSpellValue()
Definition Spell.h:595
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:2925
Position m_reflectionTargetPosition
Definition Spell.h:671
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3191
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:27
uint32 m_lastSanctuaryTime
Definition Unit.h:2073
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1470
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6678
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6512
bool CanProc()
Definition Unit.h:1542
bool IsPvP() const
Definition Unit.h:1029
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:12637
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition Unit.cpp:13741
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:11457
bool IsStandState() const
Definition Unit.cpp:16952
bool IsInCombatWith(Unit const *who) const
Definition Unit.cpp:21141
HostileRefMgr & getHostileRefMgr()
Definition Unit.h:947
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:14305
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:12513
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6544
bool IsAIEnabled
Definition Unit.h:2079
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:956
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:12757
void SetStandState(uint8 state)
Definition Unit.cpp:16967
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5307
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:814
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1327
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
Definition Position.h:27
void Relocate(float x, float y)
Definition Position.h:77
Definition Unit.h:496

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), CLASS_PALADIN, ObjectGuid::Clear(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Unit::IsClass(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_reflectionTarget, m_reflectionTargetGuid, m_reflectionTargetPosition, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Position::Relocate(), Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_SUPPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1648{
1649 if (!unitTarget)
1650 return;
1651
1652 Player* player = unitTarget->ToPlayer();
1653 if (!player)
1654 {
1655 return;
1656 }
1657
1658 uint32 newitemid = itemId;
1659
1660 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1661 if (!pProto)
1662 {
1663 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1664 return;
1665 }
1666
1667 uint32 addNumber = damage;
1668
1669 // bg reward have some special in code work
1670 bool SelfCast = true;
1671 switch (m_spellInfo->Id)
1672 {
1677 case SPELL_WS_MARK_TIE:
1680 SelfCast = true;
1681 break;
1683 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1684 addNumber = 3;
1685 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1686 addNumber = 2;
1687 else
1688 addNumber = 1;
1689 SelfCast = true;
1690 break;
1691 }
1692
1693 if (addNumber < 1)
1694 addNumber = 1;
1695 if (addNumber > pProto->GetMaxStackSize())
1696 addNumber = pProto->GetMaxStackSize();
1697
1698 /* == gem perfection handling == */
1699
1700 // the chance of getting a perfect result
1701 float perfectCreateChance = 0.0f;
1702
1703 // the resulting perfect item if successful
1704 uint32 perfectItemType = itemId;
1705
1706 // get perfection capability and chance
1707 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1708 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1709 newitemid = perfectItemType; // the perfect item replaces the regular one
1710
1711 /* == gem perfection handling over == */
1712
1713 /* == profession specialization handling == */
1714
1715 // init items_count to 1, since 1 item will be created regardless of specialization
1716 int32 itemsCount = 1;
1717 float additionalCreateChance = 0.0f;
1718 int32 additionalMaxNum = 0;
1719 // get the chance and maximum number for creating extra items
1720 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1721 {
1722 // roll with this chance till we roll not to create or we create the max num
1723 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1724 ++itemsCount;
1725 }
1726
1727 // really will be created more items
1728 addNumber *= itemsCount;
1729
1730 /* == profession specialization handling over == */
1731
1732 // can the player store the new item?
1733 ItemPosCountVec dest;
1734 uint32 no_space = 0;
1735 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1736 if (msg != EQUIP_ERR_OK)
1737 {
1738 // convert to possible store amount
1740 addNumber -= no_space;
1741 else
1742 {
1743 // if not created by another reason from full inventory or unique items amount limitation
1744 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1745 return;
1746 }
1747 }
1748
1749 if (addNumber)
1750 {
1751 // create the new item and store it
1752 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1753
1754 // was it successful? return error if not
1755 if (!pItem)
1756 {
1757 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1758 return;
1759 }
1760
1761 // set the "Crafted by ..." property of the item
1762 if (m_caster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1763 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1764
1765 // send info to the client
1766 player->SendNewItem(pItem, addNumber, true, SelfCast);
1767
1768 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1769
1770 // we succeeded in creating at least one item, so a levelup is possible
1771 if (SelfCast)
1773 }
1774}
@ SPELL_WS_MARK_WINNER
Definition Battleground.h:97
@ SPELL_AV_MARK_LOSER
Definition Battleground.h:101
@ SPELL_WS_MARK_TIE
Definition Battleground.h:98
@ SPELL_WS_MARK_LOSER
Definition Battleground.h:96
@ SPELL_AB_MARK_LOSER
Definition Battleground.h:99
@ SPELL_WG_MARK_WINNER
Definition Battleground.h:105
@ SPELL_AB_MARK_WINNER
Definition Battleground.h:100
@ SPELL_AV_MARK_WINNER
Definition Battleground.h:102
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition Item.h:64
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition SkillExtraItems.cpp:202
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:712
bool UpdateCraftSkill(uint32 spellid)
Definition PlayerUpdates.cpp:830
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4812
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2596
bool HasSignature() const
Definition ItemTemplate.h:697

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, Object::IsPlayer(), ITEM_FIELD_CREATOR, m_caster, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2926{
2927 if (!unit || !effectMask)
2928 return SPELL_MISS_EVADE;
2929
2930 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
2931 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
2932 {
2933 return SPELL_MISS_IMMUNE;
2934 }
2935
2936 // disable effects to which unit is immune
2937 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
2938 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
2939 {
2940 if (effectMask & (1 << effectNumber))
2941 {
2942 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
2943 effectMask &= ~(1 << effectNumber);
2944 // Xinef: Buggs out polymorph
2945 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
2946 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
2947 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
2948 {
2949 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2950 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2951
2952 if (debuff_resist_chance > 0)
2953 if (irand(0,10000) <= (debuff_resist_chance * 100))
2954 {
2955 effectMask &= ~(1 << effectNumber);
2956 returnVal = SPELL_MISS_RESIST;
2957 }
2958 }*/
2959 }
2960 }
2961 if (!effectMask)
2962 return returnVal;
2963
2964 if (unit->IsPlayer())
2965 {
2969 }
2970
2971 if (m_caster->IsPlayer())
2972 {
2975 }
2976
2977 if (m_caster != unit)
2978 {
2979 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
2980 // Xinef: Also check evade state
2981 if (m_spellInfo->Speed > 0.0f)
2982 {
2983 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
2984 return SPELL_MISS_EVADE;
2985
2987 return SPELL_MISS_EVADE;
2988 }
2989
2990 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
2991 {
2993 }
2994 else if (m_caster->IsFriendlyTo(unit))
2995 {
2996 // for delayed spells ignore negative spells (after duel end) for friendly targets
2998 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
2999 return SPELL_MISS_EVADE;
3000
3001 // assisting case, healing and resurrection
3003 {
3006 m_caster->ToPlayer()->UpdatePvP(true);
3007 }
3008
3009 // xinef: triggered spells should not prolong combat
3011 {
3012 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3013 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3014 }
3015 }
3016 }
3017
3018 uint8 aura_effmask = 0;
3019 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3020 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3021 aura_effmask |= 1 << i;
3022
3023 Unit* originalCaster = GetOriginalCaster();
3024 if (!originalCaster)
3025 originalCaster = m_caster;
3026
3027 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3028 // Xinef: Do not increase diminishing level for self cast
3030 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3031 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3032 {
3035
3036 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3037
3038 // Increase Diminishing on unit, current informations for actually casts will use values above
3039 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3041 {
3042 // Do not apply diminish return if caster is NPC
3044 {
3046 }
3047 }
3048 }
3049
3051 {
3053 }
3054
3055 if (aura_effmask)
3056 {
3057 // Select rank for aura with level requirements only in specific cases
3058 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3059 SpellInfo const* aurSpellInfo = m_spellInfo;
3060 int32 basePoints[3];
3061 if (scaleAura)
3062 {
3064 ASSERT(aurSpellInfo);
3065 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3066 {
3067 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3068 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3069 {
3070 aurSpellInfo = m_spellInfo;
3071 break;
3072 }
3073 }
3074 }
3075
3076 if (m_originalCaster)
3077 {
3078 bool refresh = false;
3080 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3081 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3082
3083 // xinef: if aura was not refreshed, add proc ex
3084 if (!refresh)
3086
3087 if (m_spellAura)
3088 {
3089 // Prevent aura application if target is banished and immuned
3092 {
3094 return SPELL_MISS_IMMUNE;
3095 }
3096
3097 // Set aura stack amount to desired value
3099 {
3100 if (!refresh)
3102 else
3104 }
3105
3106 // Now Reduce spell duration using data received at spell hit
3107 int32 duration = m_spellAura->GetMaxDuration();
3108 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3109
3110 // Xinef: if unit == caster - test versus original unit if available
3111 float diminishMod = 1.0f;
3112 if (unit == m_caster && m_targets.GetUnitTarget())
3114 else
3115 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3116
3117 // unit is immune to aura if it was diminished to 0 duration
3118 if (diminishMod == 0.0f)
3119 {
3122 return SPELL_MISS_IMMUNE;
3123 bool found = false;
3124 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3125 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3126 found = true;
3127 if (!found)
3128 return SPELL_MISS_IMMUNE;
3129 }
3130 else
3131 {
3132 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3133
3134 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3136 positive = aurApp->IsPositive();
3137
3138 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3139
3140 // xinef: haste affects duration of those spells twice
3143
3144 if (m_spellValue->AuraDuration != 0)
3145 {
3146 if (m_spellAura->GetMaxDuration() != -1)
3147 {
3149 }
3150
3152 }
3153 else if (duration != m_spellAura->GetMaxDuration())
3154 {
3155 m_spellAura->SetMaxDuration(duration);
3156 m_spellAura->SetDuration(duration);
3157 }
3158
3159 // xinef: apply relic cooldown, imo best place to add this
3162
3165 }
3166 }
3167 }
3168 }
3169
3170 int8 sanct_effect = -1;
3171
3172 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3173 {
3174 // handle sanctuary effects after aura apply!
3175 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3176 {
3177 sanct_effect = effectNumber;
3178 continue;
3179 }
3180
3181 if (effectMask & (1 << effectNumber))
3182 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3183 }
3184
3185 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3186 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3187
3188 return SPELL_MISS_NONE;
3189}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition CreatureData.h:64
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition CreatureData.h:65
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition SharedDefines.h:3516
@ SPELL_EFFECT_SANCTUARY
Definition SharedDefines.h:868
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:795
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition SharedDefines.h:591
DiminishingReturnsType
Definition SharedDefines.h:3489
@ DRTYPE_PLAYER
Definition SharedDefines.h:3491
@ DRTYPE_ALL
Definition SharedDefines.h:3492
@ SPELL_AURA_PERIODIC_HASTE
Definition SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:152
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition SpellMgr.cpp:272
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition SpellMgr.cpp:55
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:242
@ PROC_EX_NO_AURA_REFRESH
Definition SpellMgr.h:214
@ UNIT_STATE_ATTACK_PLAYER
Definition UnitDefines.h:184
@ UNIT_STATE_ISOLATED
Definition UnitDefines.h:183
@ UNIT_FLAG_NON_ATTACKABLE
Definition UnitDefines.h:255
@ UNIT_MOD_CAST_SPEED
Definition UpdateFields.h:137
Definition SpellAuras.h:37
int32 GetMaxDuration() const
Definition SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:937
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2671
void _RegisterForTargets()
Definition SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:963
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition SpellAuras.cpp:265
void SetDuration(int32 duration, bool withMods=false)
Definition SpellAuras.cpp:810
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:184
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
bool isWorldBoss() const
Definition Creature.h:124
bool IsInEvadeMode() const
Definition Creature.h:138
float GetFloatValue(uint16 index) const
Definition Object.cpp:306
uint32 StackAmount
Definition SpellInfo.h:371
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2422
Unit * GetOriginalCaster() const
Definition Spell.h:586
Definition SpellAuras.h:280
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:5887
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:15121
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:15147
uint32 GetCombatTimer() const
Definition Unit.h:934
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:13007
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:17501
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:737
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:15161
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:14987
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1322
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition Unit.cpp:13899
bool HasReflectSpellsAura() const
Definition Unit.h:1796
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1294
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12922
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:13091
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:13076
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:10421
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:14044
ObjectGuid GetCharmerOrOwnerGUID() const
Definition Unit.h:1280
uint32 flags_extra
Definition CreatureData.h:242
int32 AuraDuration
Definition Spell.h:227
uint8 AuraStackAmount
Definition Spell.h:226

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), Unit::HasReflectSpellsAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, UNIT_STATE_ISOLATED, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3192{
3193 // Apply additional spell effects to target
3195 if (m_preCastSpell)
3196 {
3197 // Paladin immunity shields
3198 if (m_preCastSpell == 61988)
3199 {
3200 // Cast Forbearance
3201 m_caster->CastSpell(unit, 25771, true);
3202 // Cast Avenging Wrath Marker
3203 unit->CastSpell(unit, 61987, true);
3204 }
3205
3206 // Avenging Wrath
3207 if (m_preCastSpell == 61987)
3208 // Cast the serverside immunity shield marker
3209 m_caster->CastSpell(unit, 61988, true);
3210
3211 // Fearie Fire (Feral) - damage
3212 if (m_preCastSpell == 60089)
3213 m_caster->CastSpell(unit, m_preCastSpell, true);
3214 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3215 // Blizz seems to just apply aura without bothering to cast
3217 }
3218
3219 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3220 // this is executed after spell proc spells on target hit
3221 // spells are triggered for each hit spell target
3222 // info confirmed with retail sniffs of permafrost and shadow weaving
3223 if (!m_hitTriggerSpells.empty())
3224 {
3225 int _duration = 0;
3226 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3227 {
3228 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3229 {
3230 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3231 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3232
3233 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3234 // set duration of current aura to the triggered spell
3235 if (i->triggeredSpell->GetDuration() == -1)
3236 {
3237 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3238 {
3239 // get duration from aura-only once
3240 if (!_duration)
3241 {
3242 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3243 _duration = aur ? aur->GetDuration() : -1;
3244 }
3245 triggeredAur->SetDuration(_duration);
3246 }
3247 }
3248 }
3249 }
3250 }
3251
3252 // trigger linked auras remove/apply
3254 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3255 {
3256 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3257 if (*i < 0)
3258 {
3259 unit->RemoveAurasDueToSpell(-(*i));
3260 }
3261 else
3262 {
3263 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3264 }
3265 }
3266}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:97
int32 GetDuration() const
Definition SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:769
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5707
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:19121

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4249{
4251 return;
4252
4253 if (!gameObjTarget)
4254 return;
4255
4256 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4257 switch (action)
4258 {
4264 break;
4265 case GameObjectActions::Disturb: // What's the difference with Open?
4267 if (Unit* unitCaster = m_caster->ToUnit())
4268 gameObjTarget->Use(unitCaster);
4269 break;
4271 if (Unit* unitCaster = m_caster->ToUnit())
4272 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4273 [[fallthrough]];
4277 break;
4281 break;
4284 break;
4288 break;
4292 break;
4294 if (Unit* unitCaster = m_caster->ToUnit())
4295 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4296 break;
4301 {
4302 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4303
4304 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4305
4306 uint32 artKitValue = 0;
4307 if (templateAddon)
4308 artKitValue = templateAddon->artKits[artKitIndex];
4309
4310 if (artKitValue == 0)
4311 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4312 else
4313 gameObjTarget->SetGoArtKit(artKitValue);
4314
4315 break;
4316 }
4318 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4319 break;
4320 default:
4321 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4322 break;
4323 }
4324}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:154
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1618
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1615
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1394
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1408
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2126
void ResetDoorOrButton()
Definition GameObject.cpp:1384
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:916
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:895
void Use(Unit *user)
Definition GameObject.cpp:1444
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:827
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:881
Definition GameObjectData.h:666
std::array< uint32, 4 > artKits
Definition GameObjectData.h:672

References AnimateCustom0, AnimateCustom1, AnimateCustom2, AnimateCustom3, Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, Close, CloseAndLock, Despawn, GameObject::DespawnOrUnsummon(), Destroy, Disturb, effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, Lock, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, MakeActive, MakeInert, None, Open, OpenAndUnlock, Rebuild, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), Unlock, GameObject::Use(), UseArtKit0, UseArtKit1, UseArtKit2, UseArtKit3, and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5784{
5786 return;
5787
5788 if (!m_caster->IsPlayer())
5789 return;
5790
5791 Player* player = m_caster->ToPlayer();
5792
5794 return;
5795
5796 // needed later
5798
5799 uint32 count = damage;
5800 if (count == 0) count = 1;
5801 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5802 {
5803 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5804 {
5805 if (m_spellInfo->Id == 45529)
5806 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5807 continue;
5808 player->SetRuneCooldown(j, 0);
5809 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5810 --count;
5811 }
5812 }
5813
5814 // Blood Tap
5815 if (m_spellInfo->Id == 45529 && count > 0)
5816 {
5817 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5818 {
5819 // Check if both runes are on cd as that is the only time when this needs to come into effect
5820 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5821 {
5822 // Should always update the rune with the lowest cd
5823 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5824 l++;
5825 player->SetRuneCooldown(l, 0);
5826 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5827 --count;
5828 }
5829 else
5830 break;
5831 }
5832 }
5833
5834 // Empower rune weapon
5835 if (m_spellInfo->Id == 47568)
5836 {
5837 // Need to do this just once
5838 if (effIndex != 0)
5839 return;
5840
5841 for (uint32 i = 0; i < MAX_RUNES; ++i)
5842 {
5843 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5844 {
5845 player->SetRuneCooldown(i, 0);
5846 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5847 }
5848 }
5849 }
5850
5851 // is needed to push through to the client that the rune is active
5852 //player->ResyncRunes(MAX_RUNES);
5853 m_caster->CastSpell(m_caster, 47804, true);
5854}
@ RUNE_FROST
Definition Player.h:399
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2549
uint8 GetRunesState() const
Definition Player.h:2538
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2550
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2539

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6159{
6161 return;
6162
6163 if (!unitTarget)
6164 return;
6165
6166 if (Player* player = unitTarget->ToPlayer())
6167 {
6168 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6169 }
6170}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4086{
4088 {
4089 return;
4090 }
4091
4092 if (!unitTarget || damage <= 0)
4093 {
4094 return;
4095 }
4096
4098}
void AddComboPointGain(Unit *target, int8 amount)
Definition Spell.h:541

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4668{
4670 {
4671 return;
4672 }
4673
4674 if (!unitTarget || !unitTarget->IsAlive())
4675 {
4676 return;
4677 }
4678
4680
4682}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5065
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2801

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2722{
2724 return;
2725
2726 if (!m_caster->IsPlayer())
2727 return;
2728
2729 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2730 int32 duration = m_spellInfo->GetDuration();
2731 // Caster not in world, might be spell triggered from aura removal
2732 if (!m_caster->IsInWorld())
2733 return;
2734
2735 // Remove old farsight if exist
2736 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2737
2738 DynamicObject* dynObj = new DynamicObject();
2740 {
2741 delete dynObj;
2742 return;
2743 }
2744
2745 dynObj->SetDuration(duration);
2746 dynObj->SetCasterViewpoint(updateViewerVisibility);
2747}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition DynamicObject.cpp:198
void SetCasterViewpoint(bool updateViewerVisibility)
Definition DynamicObject.cpp:226
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:481
int32 GetDuration() const
Definition SpellInfo.cpp:2232

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, DynamicObject, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2792{
2794 return;
2795
2796 if (!unitTarget->IsPlayer())
2797 return;
2798
2799 // not scale value for item based reward (/10 value expected)
2800 if (m_CastItem)
2801 {
2802 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2803 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2805 return;
2806 }
2807
2808 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2809 if (damage <= 50)
2810 {
2812 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2813 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2814 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2815 }
2816 else
2817 {
2818 //maybe we have correct honor_gain in damage already
2819 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2820 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2822 }
2823}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6091
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:38

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1320{
1322 return;
1323
1324 if (!m_spellAura || !unitTarget)
1325 return;
1328}
WorldObject * GetOwner() const
Definition SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition SpellAuras.cpp:677

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4327{
4329 return;
4330
4332 return;
4333
4334 Player* player = m_caster->ToPlayer();
4335
4336 // glyph sockets level requirement
4337 uint8 minLevel = 0;
4338 switch (m_glyphIndex)
4339 {
4340 case 0:
4341 case 1:
4342 minLevel = 15;
4343 break;
4344 case 2:
4345 minLevel = 50;
4346 break;
4347 case 3:
4348 minLevel = 30;
4349 break;
4350 case 4:
4351 minLevel = 70;
4352 break;
4353 case 5:
4354 minLevel = 80;
4355 break;
4356 }
4357 if (minLevel && m_caster->GetLevel() < minLevel)
4358 {
4360 return;
4361 }
4362
4363 // apply new one
4364 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4365 {
4366 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4367 {
4368 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4369 {
4370 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4371 {
4373 return; // glyph slot mismatch
4374 }
4375 }
4376
4377 // remove old glyph aura
4378 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4379 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4380 {
4381 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4382
4383 // Removed any triggered auras
4384 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4385 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4386 {
4387 Aura* aura = iter->second;
4388 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4389 {
4390 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4391 {
4392 player->RemoveOwnedAura(iter);
4393 continue;
4394 }
4395 }
4396 ++iter;
4397 }
4398
4399 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4400 }
4401
4402 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4404 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4405 player->SendTalentsInfoData(false);
4406 }
4407 }
4408}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
#define MAX_GLYPH_SLOT_INDEX
Definition SharedDefines.h:687
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition SharedDefines.h:1137
@ SPELL_FAILED_INVALID_GLYPH
Definition SharedDefines.h:1135
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition SpellDefines.h:150
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition SpellAuras.cpp:2685
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14526
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3018
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1781
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1772
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1773
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4824
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:660
AuraMap & GetOwnedAuras()
Definition Unit.h:1358
bool PlayerLoading() const
Definition WorldSession.h:401
Definition DBCStructure.h:1032

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6292{
6294 return;
6295
6296 if (!unitTarget)
6297 return;
6298
6299 Player* player = unitTarget->ToPlayer();
6300 if (!player)
6301 {
6302 return;
6303 }
6304
6305 WorldLocation homeLoc;
6306 uint32 areaId = player->GetAreaId();
6307
6308 if (m_spellInfo->Effects[effIndex].MiscValue)
6309 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6310
6311 if (m_targets.HasDst())
6312 homeLoc.WorldRelocate(*destTarget);
6313 else
6314 {
6315 homeLoc = player->GetWorldLocation();
6316 }
6317
6318 player->SetHomebind(homeLoc, areaId);
6319
6320 // binding
6321 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6322 data << float(homeLoc.GetPositionX());
6323 data << float(homeLoc.GetPositionY());
6324 data << float(homeLoc.GetPositionZ());
6325 data << uint32(homeLoc.GetMapId());
6326 data << uint32(areaId);
6327 player->SendDirectMessage(&data);
6328
6329 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6330 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6331 // zone update
6332 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6333 data << m_caster->GetGUID();
6334 data << uint32(areaId);
6335 player->SendDirectMessage(&data);
6336}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5685
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4958
Definition Position.h:256
void WorldRelocate(const WorldLocation &loc)
Definition Position.h:264
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition Position.h:286
@ SMSG_BINDPOINTUPDATE
Definition Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition Opcodes.h:374

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4694{
4696 return;
4697
4698 if (m_caster->IsPlayer())
4699 m_caster->ToPlayer()->SetCanBlock(true);
4700}
void SetCanBlock(bool value)
Definition Player.cpp:13155

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6219{
6221 return;
6222
6223 if (!m_caster->IsPlayer())
6224 return;
6225
6226 Player* p_caster = m_caster->ToPlayer();
6227 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6228 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6229
6230 for (; n_buttons; --n_buttons, ++button_id)
6231 {
6232 ActionButton const* ab = p_caster->GetActionButton(button_id);
6233 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6234 continue;
6235
6238 uint32 spell_id = ab->GetAction();
6239 if (!spell_id)
6240 continue;
6241
6242 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6243 if (!spellInfo)
6244 continue;
6245
6246 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6247 continue;
6248
6250 continue;
6251
6252 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6253 if (m_caster->GetPower(POWER_MANA) < cost)
6254 continue;
6255
6257 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6258 }
6259}
@ ACTION_BUTTON_SPELL
Definition Player.h:223
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition SharedDefines.h:657
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:5644
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3877
Definition Player.h:241
uint32 GetAction() const
Definition Player.h:249
ActionButtonType GetType() const
Definition Player.h:248

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4913{
4915 {
4916 if (!unitTarget)
4917 return;
4918
4919 ObjectGuid targetGUID = ObjectGuid::Empty;
4920 Player* player = m_caster->ToPlayer();
4921 if (player)
4922 {
4923 // charge changes fall time
4925
4927 {
4928 targetGUID = unitTarget->GetGUID();
4929 }
4930 }
4931
4932 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4933 // Spell is not using explicit target - no generated path
4934 if (!m_preGeneratedPath)
4935 {
4937 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4938 }
4939 else
4940 {
4941 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4942 }
4943
4944 if (player)
4945 {
4946 sScriptMgr->AnticheatSetUnderACKmount(player);
4947 }
4948 }
4949}
#define SPEED_CHARGE
Definition MotionMaster.h:134
@ EVENT_CHARGE
Definition SharedDefines.h:3567
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:719
static ObjectGuid const Empty
Definition ObjectGuid.h:120
void SetFallInformation(uint32 time, float z)
Definition Player.h:2369
MotionMaster * GetMotionMaster()
Definition Unit.h:1738
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2858
float m_positionZ
Definition Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition Position.h:201
float m_positionX
Definition Position.h:55
float m_positionY
Definition Position.h:56

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1777{
1779 return;
1780
1781 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1782 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1783}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5093
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition SpellEffects.cpp:1647

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1786{
1788 return;
1789
1790 if (!unitTarget)
1791 return;
1792
1793 Player* player = unitTarget->ToPlayer();
1794 if (!player)
1795 {
1796 return;
1797 }
1798
1799 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1800
1801 if (itemId)
1802 DoCreateItem(effIndex, itemId);
1803
1804 // special case: fake item replaced by generate using spell_loot_template
1806 {
1807 if (itemId)
1808 {
1809 if (!player->HasItemCount(itemId))
1810 return;
1811
1812 // remove reagent
1813 uint32 count = 1;
1814 player->DestroyItemCount(itemId, count, true);
1815
1816 // create some random items
1818 }
1819 else
1820 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1821 }
1823}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition Player.cpp:13510
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3182
bool IsLootCrafting() const
Definition SpellInfo.cpp:925

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1826{
1828 return;
1829
1830 if (!unitTarget)
1831 return;
1832
1833 Player* player = unitTarget->ToPlayer();
1834 if (!player)
1835 {
1836 return;
1837 }
1838
1839 // create some random items
1842}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5857{
5859 return;
5860
5862 return;
5863
5864 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5865 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5866 if (!pet)
5867 return;
5868
5869 // add to world
5870 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5871
5872 // unitTarget has pet now
5873 unitTarget->SetMinion(pet, true);
5874
5875 pet->InitTalentForLevel();
5876
5877 if (unitTarget->IsPlayer())
5878 {
5881 }
5882}
@ CLASS_HUNTER
Definition SharedDefines.h:143
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:305
void InitTalentForLevel()
Definition Pet.cpp:2210
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9499
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:10895
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:17604

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5264{
5266 return;
5267
5268 int32 mana = 0;
5269 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5270 {
5271 if (!m_caster->m_SummonSlot[slot])
5272 continue;
5273
5275 if (totem && totem->IsTotem())
5276 {
5277 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5278 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5279 if (spellInfo)
5280 {
5281 mana += spellInfo->ManaCost;
5283 }
5284 totem->ToTotem()->UnSummon();
5285 }
5286 }
5287 ApplyPct(mana, damage);
5288 if (mana)
5289 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5290}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3562
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3552
@ UNIT_CREATED_BY_SPELL
Definition UpdateFields.h:138
T ApplyPct(T &base, U pct)
Definition Util.h:64
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2357
uint32 ManaCostPercentage
Definition SpellInfo.h:367
uint32 ManaCost
Definition SpellInfo.h:363
void UnSummon(Milliseconds msTime=0ms) override
Definition Totem.cpp:122
Totem * ToTotem()
Definition Unit.h:720
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1251
uint32 GetCreateMana() const
Definition Unit.h:1133
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2061

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM_FIRE, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5885{
5887 return;
5888
5889 if (!unitTarget)
5890 return;
5891
5892 Player* player = unitTarget->ToPlayer();
5893 if (!player)
5894 {
5895 return;
5896 }
5897
5898 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5899 if (sTaxiNodesStore.LookupEntry(nodeid))
5900 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5901}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4464{
4466 return;
4467
4469 return;
4470
4471 if (Player* caster = m_caster->ToPlayer())
4472 {
4473 caster->UpdateCraftSkill(m_spellInfo->Id);
4474 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4475 }
4476
4477 // item will be removed at disenchanting end
4478}
@ LOOT_DISENCHANTING
Definition LootMgr.h:83

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4550{
4552 return;
4553
4554 if (!unitTarget || !unitTarget->IsPet())
4555 return;
4556
4557 Pet* pet = unitTarget->ToPet();
4558
4559 ExecuteLogEffectUnsummonObject(effIndex, pet);
4561}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:881
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5111

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2571{
2573 return;
2574
2575 if (!unitTarget)
2576 return;
2577
2578 // Create dispel mask by dispel type
2579 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2580 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2581
2582 DispelChargesList dispel_list;
2583 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2584 if (dispel_list.empty())
2585 return;
2586
2587 // Ok if exist some buffs for dispel try dispel it
2588 uint32 failCount = 0;
2589 DispelChargesList success_list;
2590 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2591 // dispel N = damage buffs (or while exist buffs for dispel)
2592 for (int32 count = 0; count < damage && !dispel_list.empty();)
2593 {
2594 // Random select buff for dispel
2595 DispelChargesList::iterator itr = dispel_list.begin();
2596 std::advance(itr, urand(0, dispel_list.size() - 1));
2597
2598 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2599 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2600 if (!chance)
2601 {
2602 dispel_list.erase(itr);
2603 continue;
2604 }
2605 else
2606 {
2607 if (roll_chance_i(chance))
2608 {
2609 bool alreadyListed = false;
2610 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2611 {
2612 if (successItr->first->GetId() == itr->first->GetId())
2613 {
2614 ++successItr->second;
2615 alreadyListed = true;
2616 }
2617 }
2618 if (!alreadyListed)
2619 success_list.push_back(std::make_pair(itr->first, 1));
2620 --itr->second;
2621 if (itr->second <= 0)
2622 dispel_list.erase(itr);
2623 }
2624 else
2625 {
2626 if (!failCount)
2627 {
2628 // Failed to dispell
2629 dataFail << m_caster->GetGUID(); // Caster GUID
2630 dataFail << unitTarget->GetGUID(); // Victim GUID
2631 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2632 }
2633 ++failCount;
2634 dataFail << uint32(itr->first->GetId()); // Spell Id
2635 }
2636 ++count;
2637 }
2638 }
2639
2640 if (failCount)
2641 m_caster->SendMessageToSet(&dataFail, true);
2642
2643 // put in combat
2646
2647 if (success_list.empty())
2648 return;
2649
2650 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2651 // Send packet header
2652 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2653 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2654 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2655 dataSuccess << uint8(0); // not used
2656 dataSuccess << uint32(success_list.size()); // count
2657 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2658 {
2659 // Send dispelled spell info
2660 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2661 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2662 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2663 }
2664 m_caster->SendMessageToSet(&dataSuccess, true);
2665
2666 // On success dispel
2667 // Devour Magic
2669 {
2670 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2671 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2672 // Glyph of Felhunter
2673 if (Unit* owner = m_caster->GetOwner())
2674 if (owner->GetAura(56249))
2675 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2676 }
2677}
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3789
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition SpellMgr.h:40
uint32 GetCategory() const
Definition SpellInfo.cpp:871
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition Unit.cpp:5061
@ SMSG_DISPEL_FAILED
Definition Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition Opcodes.h:665

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5169{
5171 return;
5172
5173 if (!unitTarget)
5174 return;
5175
5176 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5177
5178 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5179
5180 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5181 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5182 {
5183 Aura* aura = itr->second;
5185 continue;
5187 {
5188 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5189 {
5190 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5191
5192 // spell only removes 1 bleed effect do not continue
5193 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5194 {
5195 break;
5196 }
5197 }
5198 }
5199 }
5200
5201 for (; dispel_list.size(); dispel_list.pop())
5202 {
5203 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5204 }
5205
5206 // put in combat
5209}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:105
uint32 GetId() const
Definition SpellAuras.cpp:405
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition SpellAuras.cpp:1134
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4895

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2694{
2696 return;
2697
2698 // Check for possible target
2699 if (!unitTarget || unitTarget->IsEngaged())
2700 return;
2701
2702 // target must be OK to do this
2704 return;
2705
2708}
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:181
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:177
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:173
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition MotionMaster.cpp:847
void SetFacingTo(float ori)
Definition Unit.cpp:20507
bool IsEngaged() const
Definition Unit.h:921
float GetAngle(const Position *pos) const
Definition Position.cpp:85

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2680{
2682 return;
2683
2685}
virtual void SetCanDualWield(bool value)
Definition Unit.h:964

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4101{
4103 return;
4104
4105 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4106 return;
4107
4108 Player* caster = m_caster->ToPlayer();
4109 Player* target = unitTarget->ToPlayer();
4110
4111 // caster or target already have requested duel
4112 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4113 return;
4114
4115 // Players can only fight a duel in zones with this flag
4116 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4117 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4118 {
4119 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4120 return;
4121 }
4122
4123 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4124 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4125 {
4126 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4127 return;
4128 }
4129
4130 //CREATE DUEL FLAG OBJECT
4131 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4132 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4133
4134 Map* map = m_caster->GetMap();
4135 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4136 map, m_caster->GetPhaseMask(),
4140 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4141 {
4142 delete pGameObj;
4143 return;
4144 }
4145
4148 int32 duration = m_spellInfo->GetDuration();
4149 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4150 pGameObj->SetSpellId(m_spellInfo->Id);
4151
4152 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4153
4154 m_caster->AddGameObject(pGameObj);
4155 map->AddToMap(pGameObj, true);
4156 //END
4157
4158 // Send request
4159 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4160 data << pGameObj->GetGUID();
4161 data << caster->GetGUID();
4162 caster->SendDirectMessage(&data);
4163 target->SendDirectMessage(&data);
4164
4165 // create duel-info
4166 bool isMounted = (GetSpellInfo()->Id == 62875);
4167 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4168 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4169
4170 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4171 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4172
4173 sScriptMgr->OnPlayerDuelRequest(target, caster);
4174}
@ AREA_FLAG_ALLOW_DUELS
Definition DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition SharedDefines.h:1039
@ PLAYER_DUEL_ARBITER
Definition UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition UpdateFields.h:402
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition GameObject.cpp:259
void SetRespawnTime(int32 respawn)
Definition GameObject.cpp:1268
void SetSpellId(uint32 id)
Definition GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:639
bool HasIgnore(ObjectGuid const &ignore_guid) const
Definition SocialMgr.cpp:193
PlayerSocial * GetSocial()
Definition Player.h:1157
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5105
Definition Transport.h:115
uint32 GetFaction() const
Definition Unit.h:841
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6413
uint32 GetPhaseMask() const
Definition Object.h:512
@ SMSG_DUEL_REQUESTED
Definition Opcodes.h:389
uint32 flags
Definition DBCStructure.h:524
float GetOrientation() const
Definition Position.h:124

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GameObject, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), Player::SendDirectMessage(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
663{
665 return;
666
668 return;
669
670 // selection by spell family
672 {
674 {
675 switch (m_spellInfo->Id)
676 {
677 // Trial of the Champion, Trample
678 case 67866:
679 {
681 unitTarget->CastSpell(unitTarget, 67867, false);
682 return;
683 }
684 // Trial of the Champion, Hammer of the Righteous
685 case 66867:
686 {
687 if (!unitTarget)
688 return;
689 if (unitTarget->HasAura(66940))
690 m_caster->CastSpell(unitTarget, 66903, true);
691 else
692 m_caster->CastSpell(unitTarget, 66904, true);
693 return;
694 }
695 case 17731:
696 case 69294:
697 {
699 return;
700
704 trigger->CastSpell(trigger, 17731, false);
705
706 return;
707 }
708 // HoL, Arc Weld
709 case 59086:
710 {
712 m_caster->CastSpell(m_caster, 59097, true);
713
714 return;
715 }
716 }
717 break;
718 }
720 switch (m_spellInfo->Id)
721 {
722 case 31789: // Righteous Defense (step 1)
723 {
724 if (!unitTarget)
725 return;
726 // not empty (checked), copy
728
729 // remove invalid attackers
730 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
731 if (!(*aItr)->IsValidAttackTarget(m_caster))
732 aItr = attackers.erase(aItr);
733 else
734 ++aItr;
735
736 // selected from list 3
737 uint32 maxTargets = std::min<uint32>(3, attackers.size());
738 for (uint32 i = 0; i < maxTargets; ++i)
739 {
740 Unit::AttackerSet::iterator aItr = attackers.begin();
741 std::advance(aItr, urand(0, attackers.size() - 1));
742 m_caster->CastSpell((*aItr), 31790, true);
743 attackers.erase(aItr);
744 }
745
746 return;
747 }
748 }
749 break;
751 // Hunger for Blood
752 if (m_spellInfo->Id == 51662)
753 {
754 m_caster->CastSpell(m_caster, 63848, true);
755 return;
756 }
757 break;
758 }
759
760 // pet auras
761 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
762 {
763 m_caster->AddPetAura(petSpell);
764 return;
765 }
766
767 // normal DB scripted effect
768 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
770
771 if (gameObjTarget)
772 {
773 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
774 }
775 else if (unitTarget && unitTarget->IsCreature())
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
778 }
779 else if (itemTarget)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
782 }
783}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:59
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:50
@ SPELLFAMILY_GENERIC
Definition SharedDefines.h:3784
@ SPELLFAMILY_PALADIN
Definition SharedDefines.h:3794
@ SPELLFAMILY_ROGUE
Definition SharedDefines.h:3792
@ UNIT_FIELD_MOUNTDISPLAYID
Definition UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition GameObject.h:208
time_t GetRespawnTime() const
Definition GameObject.h:183
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition MapScripts.cpp:31
Definition SpellMgr.h:463
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:17550
std::unordered_set< Unit * > AttackerSet
Definition Unit.h:657
AttackerSet const & getAttackers() const
Definition Unit.h:890
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition Object.cpp:2364

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5293{
5295 return;
5296
5297 if (!unitTarget)
5298 return;
5299
5300 Player* player = unitTarget->ToPlayer();
5301 if (!player)
5302 {
5303 return;
5304 }
5305
5306 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5307
5308 // -1 means all player equipped items and -2 all items
5309 if (slot < 0)
5310 {
5311 player->DurabilityPointsLossAll(damage, (slot < -1));
5313 return;
5314 }
5315
5316 // invalid slot value
5317 if (slot >= INVENTORY_SLOT_BAG_END)
5318 return;
5319
5320 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5321 {
5322 player->DurabilityPointsLoss(item, damage);
5323 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5324 }
5325}
@ INVENTORY_SLOT_BAG_END
Definition Player.h:687
#define INVENTORY_SLOT_BAG_0
Definition Player.h:657
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:443
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4674
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4700
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5079

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5328{
5330 return;
5331
5332 if (!unitTarget)
5333 return;
5334
5335 Player* player = unitTarget->ToPlayer();
5336 if (!player)
5337 {
5338 return;
5339 }
5340
5341 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5342
5343 // FIXME: some spells effects have value -1/-2
5344 // Possibly its mean -1 all player equipped items and -2 all items
5345 if (slot < 0)
5346 {
5347 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5348 return;
5349 }
5350
5351 // invalid slot value
5352 if (slot >= INVENTORY_SLOT_BAG_END)
5353 return;
5354
5355 if (damage <= 0)
5356 return;
5357
5358 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5359 player->DurabilityLoss(item, float(damage) / 100.0f);
5360}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4630
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4656

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4411{
4413 return;
4414
4415 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4416 if (!unitTarget)
4417 return;
4418
4419 Player* item_owner = unitTarget->ToPlayer();
4420 if (!item_owner)
4421 {
4422 return;
4423 }
4424
4426 if (!item)
4427 return;
4428
4429 // must be equipped
4430 if (!item->IsEquipped())
4431 return;
4432
4433 if (m_spellInfo->Effects[effIndex].MiscValue)
4434 {
4435 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4436 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4437 if (!duration)
4438 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4439 if (!duration)
4440 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4441
4442 // Xinef: Venomhide poison, no other spell uses this effect...
4443 if (m_spellInfo->Id == 14792)
4444 duration = 5 * MINUTE * IN_MILLISECONDS;
4445
4446 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4447 if (!pEnchant)
4448 return;
4449
4450 // Always go to temp enchantment slot
4452
4453 // Enchantment will not be applied if a different one already exists
4454 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4455 return;
4456
4457 // Apply the temporary enchantment
4458 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4459 item_owner->ApplyEnchantment(item, slot, true);
4460 }
4461}
EnchantmentSlot
Definition Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition Item.h:170
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:677
bool IsEquipped() const
Definition Item.cpp:789
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:920
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition PlayerStorage.cpp:4371
uint32 charges
Definition DBCStructure.h:1843

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2838{
2840 return;
2841
2842 if (!m_caster->IsPlayer())
2843 return;
2844 if (!itemTarget)
2845 return;
2846
2847 Player* p_caster = m_caster->ToPlayer();
2848
2849 // Handle vellums
2851 {
2852 // destroy one vellum from stack
2853 uint32 count = 1;
2854 p_caster->DestroyItemCount(itemTarget, count, true);
2855 unitTarget = p_caster;
2856 // and add a scroll
2857 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2858 itemTarget = nullptr;
2859 m_targets.SetItemTarget(nullptr);
2860 }
2861 else
2862 {
2863 // do not increase skill if vellum used
2865 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2866
2867 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2868 if (!enchant_id)
2869 return;
2870
2871 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2872 if (!pEnchant)
2873 return;
2874
2875 // item can be in trade slot and have owner diff. from caster
2876 Player* item_owner = itemTarget->GetOwner();
2877 if (!item_owner)
2878 return;
2879
2880 // remove old enchanting before applying new if equipped
2882
2884
2885 // add new enchanting if equipped
2887
2888 item_owner->RemoveTradeableItem(itemTarget);
2890 }
2891}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4206
void SetItemTarget(Item *item)
Definition Spell.cpp:327

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2894{
2896 return;
2897
2898 if (!m_caster->IsPlayer())
2899 return;
2900 if (!itemTarget)
2901 return;
2902
2903 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2904 if (!enchant_id)
2905 return;
2906
2907 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2908 if (!pEnchant)
2909 return;
2910
2911 // support only enchantings with add socket in this slot
2912 {
2913 bool add_socket = false;
2914 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2915 {
2916 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2917 {
2918 add_socket = true;
2919 break;
2920 }
2921 }
2922 if (!add_socket)
2923 {
2924 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2926 return;
2927 }
2928 }
2929
2930 // item can be in trade slot and have owner diff. from caster
2931 Player* item_owner = itemTarget->GetOwner();
2932 if (!item_owner)
2933 return;
2934
2935 // remove old enchanting before applying new if equipped
2937
2939
2940 // add new enchanting if equipped
2942
2943 item_owner->RemoveTradeableItem(itemTarget);
2945}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2948{
2950 return;
2951
2952 if (!m_caster->IsPlayer())
2953 return;
2954
2955 Player* p_caster = m_caster->ToPlayer();
2956
2957 // Rockbiter Weapon apply to both weapon
2958 if (!itemTarget)
2959 return;
2961 {
2962 uint32 spell_id = 0;
2963
2964 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2965 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2966 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2967 switch (damage)
2968 {
2969 // Rank 1
2970 case 2:
2971 spell_id = 36744;
2972 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2973 // Rank 2
2974 case 4:
2975 spell_id = 36753;
2976 break; // 0% [ 7% == 4, 14% == 4]
2977 case 5:
2978 spell_id = 36751;
2979 break; // 20%
2980 // Rank 3
2981 case 6:
2982 spell_id = 36754;
2983 break; // 0% [ 7% == 6, 14% == 6]
2984 case 7:
2985 spell_id = 36755;
2986 break; // 20%
2987 // Rank 4
2988 case 9:
2989 spell_id = 36761;
2990 break; // 0% [ 7% == 6]
2991 case 10:
2992 spell_id = 36758;
2993 break; // 14%
2994 case 11:
2995 spell_id = 36760;
2996 break; // 20%
2997 default:
2998 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2999 return;
3000 }
3001
3002 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
3003 if (!spellInfo)
3004 {
3005 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3006 return;
3007 }
3008
3009 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3010 {
3011 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3012 {
3013 if (item->IsFitToSpellRequirements(m_spellInfo))
3014 {
3015 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3016 SpellCastTargets targets;
3017 targets.SetItemTarget(item);
3018 spell->prepare(&targets);
3019 }
3020 }
3021 }
3022 return;
3023 }
3024 if (!itemTarget)
3025 return;
3026
3027 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3028
3029 if (!enchant_id)
3030 {
3031 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3032 return;
3033 }
3034
3035 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3036 if (!pEnchant)
3037 {
3038 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3039 return;
3040 }
3041
3042 // select enchantment duration
3043 uint32 duration;
3044
3045 // rogue family enchantments exception by duration
3046 if (m_spellInfo->Id == 38615)
3047 duration = 1800; // 30 mins
3048 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3050 duration = 3600; // 1 hour
3051 // shaman family enchantments
3053 duration = 1800; // 30 mins
3054 // other cases with this SpellVisual already selected
3055 else if (m_spellInfo->SpellVisual[0] == 215)
3056 duration = 1800; // 30 mins
3057 // some fishing pole bonuses except Glow Worm which lasts full hour
3058 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3059 duration = 600; // 10 mins
3060 // shaman rockbiter enchantments
3061 else if (m_spellInfo->SpellVisual[0] == 0)
3062 duration = 1800; // 30 mins
3063 else if (m_spellInfo->Id == 29702)
3064 duration = 300; // 5 mins
3065 else if (m_spellInfo->Id == 37360)
3066 duration = 300; // 5 mins
3067 // default case
3068 else
3069 duration = 3600; // 1 hour
3070
3071 // item can be in trade slot and have owner diff. from caster
3072 Player* item_owner = itemTarget->GetOwner();
3073 if (!item_owner)
3074 return;
3075
3076 // remove old enchanting before applying new if equipped
3078
3079 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3080
3081 // add new enchanting if equipped
3083
3084 item_owner->RemoveTradeableItem(itemTarget);
3086}
@ SPELLFAMILY_SHAMAN
Definition SharedDefines.h:3795
WeaponAttackType
Definition Unit.h:215
Definition Spell.h:119
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:379
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3403

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1879{
1881 return;
1882
1883 if (!unitTarget)
1884 return;
1885 if (!unitTarget->IsAlive())
1886 return;
1887
1889 {
1891 return;
1892 }
1893
1894 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1895 return;
1896
1897 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1898
1901 return;
1902
1903 if (unitTarget->GetMaxPower(power) == 0)
1904 return;
1905
1906 // Some level depends spells
1907 int level_multiplier = 0;
1908 int level_diff = 0;
1909 switch (m_spellInfo->Id)
1910 {
1911 case 9512: // Restore Energy
1912 level_diff = m_caster->GetLevel() - 40;
1913 level_multiplier = 2;
1914 break;
1915 case 24571: // Blood Fury
1916 level_diff = m_caster->GetLevel() - 60;
1917 level_multiplier = 10;
1918 break;
1919 case 24532: // Burst of Energy
1920 level_diff = m_caster->GetLevel() - 60;
1921 level_multiplier = 4;
1922 break;
1923 case 31930: // Judgements of the Wise
1924 case 63375: // Improved Stormstrike
1925 case 68082: // Glyph of Seal of Command
1927 break;
1928 case 48542: // Revitalize
1930 break;
1931 case 71132: // Glyph of Shadow Word: Pain
1932 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1933 break;
1934 default:
1935 break;
1936 }
1937
1938 if (level_diff > 0)
1939 damage -= level_multiplier * level_diff;
1940
1941 if (damage < 0)
1942 return;
1943
1945
1946 // Mad Alchemist's Potion
1947 if (m_spellInfo->Id == 45051)
1948 {
1949 // find elixirs on target
1950 bool guardianFound = false;
1951 bool battleFound = false;
1953 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1954 {
1955 if (!guardianFound && sSpellMgr->IsSpellMemberOfSpellGroup(itr->second->GetBase()->GetId(), SPELL_GROUP_ELIXIR_GUARDIAN))
1956 guardianFound = true;
1957 if (!battleFound && sSpellMgr->IsSpellMemberOfSpellGroup(itr->second->GetBase()->GetId(), SPELL_GROUP_ELIXIR_BATTLE))
1958 battleFound = true;
1959 if (battleFound && guardianFound)
1960 break;
1961 }
1962
1963 // get all available elixirs by mask and spell level
1964 std::set<uint32> availableElixirs;
1965 if (!guardianFound)
1966 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_GUARDIAN, availableElixirs);
1967 if (!battleFound)
1968 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, availableElixirs);
1969 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1970 {
1971 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1972 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1973 availableElixirs.erase(itr++);
1974 else
1975 ++itr;
1976 }
1977
1978 if (!availableElixirs.empty())
1979 {
1980 // cast random elixir on target
1982 }
1983 }
1984}
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition SharedDefines.h:668
@ SPELLFAMILY_POTION
Definition SharedDefines.h:3797
@ SPELL_GROUP_ELIXIR_BATTLE
Definition SpellMgr.h:336
@ SPELL_GROUP_ELIXIR_GUARDIAN
Definition SpellMgr.h:337
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition Unit.cpp:11484
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:6702
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:133

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), GetSpellInfo(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), Unit::SendSpellDamageImmune(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_ELIXIR_BATTLE, SPELL_GROUP_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1987{
1989 return;
1990
1991 if (!unitTarget)
1992 return;
1993 if (!unitTarget->IsAlive())
1994 return;
1995
1996 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1997 return;
1998
1999 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2000
2002 return;
2003
2004 uint32 maxPower = unitTarget->GetMaxPower(power);
2005 if (maxPower == 0)
2006 return;
2007
2008 uint32 gain = CalculatePct(maxPower, damage);
2010}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
299{
301 return;
302
303 if (!unitTarget || !unitTarget->IsAlive())
304 return;
305
306 if (unitTarget->IsPlayer())
308 else
309 {
311
312 uint32 absorb = dmgInfo.GetAbsorb();
313 uint32 resist = dmgInfo.GetResist();
314 uint32 envDamage = dmgInfo.GetDamage();
315
316 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
317 damage = envDamage;
318
320 }
321}
@ DAMAGE_FIRE
Definition Player.h:833
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:773

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4517{
4519 return;
4520
4521 Player* player = m_caster->ToPlayer();
4522 if (!player)
4523 return;
4524
4525 Item* foodItem = itemTarget;
4526 if (!foodItem)
4527 return;
4528
4529 Pet* pet = player->GetPet();
4530 if (!pet)
4531 return;
4532
4533 if (!pet->IsAlive())
4534 return;
4535
4536 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4537 if (benefit <= 0)
4538 return;
4539
4540 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4541
4542 uint32 count = 1;
4543 player->DestroyItemCount(foodItem, count, true);
4545
4546 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4547}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5099

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
997{
999 return;
1000
1001 if (!unitTarget)
1002 return;
1003
1004 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1005
1006 // normal case
1007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1008
1009 if (!spellInfo)
1010 {
1011 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1016 {
1017 switch (m_spellInfo->Id)
1018 {
1019 case 52588: // Skeletal Gryphon Escape
1020 case 48598: // Ride Flamebringer Cue
1022 break;
1023 case 52463: // Hide In Mine Car
1024 case 52349: // Overtake
1025 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1026 return;
1027 case 72378: // Blood Nova
1028 case 73058: // Blood Nova
1029 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1030 break;
1031 }
1032 }
1033
1034 CustomSpellValues values;
1035 // set basepoints for trigger with value effect
1037 {
1038 // maybe need to set value only when basepoints == 0?
1042 }
1043
1044 SpellCastTargets targets;
1045 targets.SetUnitTarget(m_caster);
1046
1047 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1048}
@ SPELL_EFFECT_FORCE_CAST
Definition SharedDefines.h:929
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition SharedDefines.h:930
@ SPELLVALUE_BASE_POINT1
Definition SpellDefines.h:114
@ SPELLVALUE_BASE_POINT2
Definition SpellDefines.h:115
@ SPELLVALUE_BASE_POINT0
Definition SpellDefines.h:113
Definition SpellDefines.h:165
void AddSpellMod(SpellValueMod mod, int32 value)
Definition SpellDefines.h:167

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4773{
4775 return;
4776
4777 // xinef: clear focus
4779
4781 data << m_caster->GetGUID();
4782
4784 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4785 Cell::VisitObjects(m_caster, notifier, dist);
4786
4787 // xinef: we should also force pets to remove us from current target
4788 Unit::AttackerSet attackerSet;
4789 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4790 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4791 attackerSet.insert(*itr);
4792
4793 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4794 (*itr)->AttackStop();
4795
4796 // Xinef: Mirror images code Initialize Images
4797 if (m_spellInfo->Id == 58836)
4798 {
4799 std::vector<Unit*> images;
4800 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4801 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4802 images.push_back(*itr);
4803
4804 if (images.empty())
4805 return;
4806
4807 UnitList targets;
4808 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4811 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4812 {
4813 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4814 continue;
4815
4816 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4817 {
4818 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4819 {
4820 SpellInfo const* si = spell->GetSpellInfo();
4821 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4822 {
4823 Creature* c = (*iter)->ToCreature();
4824 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4825 continue;
4826 }
4827
4828 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4829 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4830 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4831 {
4832 // at least one effect truly targets an unit, interrupt the spell
4833 interrupt = true;
4834 break;
4835 }
4836
4837 if (interrupt)
4838 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4839 }
4840 }
4841 }
4842 }
4843}
#define VISIBILITY_COMPENSATION
Definition ObjectDefines.h:26
@ CREATURE_ELITE_WORLDBOSS
Definition SharedDefines.h:2974
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition SharedDefines.h:628
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:102
std::list< Unit * > UnitList
Definition Unit.h:78
Definition GridNotifiers.h:852
bool IsDungeonBoss() const
Definition Creature.cpp:3123
ControlSet m_Controlled
Definition Unit.h:2057
void SendClearTarget()
Definition Unit.cpp:20312
@ SMSG_CLEAR_TARGET
Definition Opcodes.h:989
Definition GridNotifiers.h:134
Definition GridNotifiers.h:414
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
uint32 rank
Definition CreatureData.h:206

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, and Cell::VisitObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5929{
5931 return;
5932
5933 if (!gameObjTarget)
5934 return;
5935
5936 Unit* caster = m_originalCaster;
5937 if (!caster)
5938 return;
5939
5940 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5942 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5943 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5945}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2251
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:10219
Definition DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition DBCStructure.h:951

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5959{
5961 return;
5962
5964 return;
5965
5968}
GameObjectDestructibleState
Definition SharedDefines.h:1637
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2314

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1473{
1475 return;
1476
1477 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1478 {
1479 // Try to get original caster
1481
1482 // Skip if m_originalCaster not available
1483 if (!caster)
1484 return;
1485
1486 int32 addhealth = damage;
1487
1488 // Vessel of the Naaru (Vial of the Sunwell trinket)
1489 if (m_spellInfo->Id == 45064)
1490 {
1491 // Amount of heal - depends from stacked Holy Energy
1492 int damageAmount = 0;
1493 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1494 {
1495 damageAmount += aurEff->GetAmount();
1497 }
1498
1499 addhealth += damageAmount;
1500 }
1501 // Swiftmend - consumes Regrowth or Rejuvenation
1503 {
1505 // find most short by duration
1506 AuraEffect* forcedTargetAura = nullptr;
1507 AuraEffect* targetAura = nullptr;
1508 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1509 {
1510 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1511 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1512 {
1513 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1514 {
1515 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1516 forcedTargetAura = *i;
1517 }
1518 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1519 targetAura = *i;
1520 }
1521 }
1522
1523 if (forcedTargetAura)
1524 targetAura = forcedTargetAura;
1525
1526 if (!targetAura)
1527 {
1528 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1529 return;
1530 }
1531
1532 int32 tickheal = targetAura->GetAmount();
1533 if (Unit* auraCaster = targetAura->GetCaster())
1534 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1535
1536 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1537 //It is said that talent bonus should not be included
1538
1539 int32 tickcount = 0;
1540 // Rejuvenation
1541 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1542 tickcount = 4;
1543 // Regrowth
1544 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1545 tickcount = 6;
1546
1547 addhealth += tickheal * tickcount;
1548
1549 // Glyph of Swiftmend
1550 if (!caster->HasAura(54824))
1551 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1552
1553 //addhealth += tickheal * tickcount;
1554 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1555 }
1556 // Death Pact - return pct of max health to caster
1558 {
1559 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1560 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1561 }
1562 else if (m_spellInfo->Id != 33778) // not lifebloom
1563 {
1564 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1565 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1566 }
1567
1568 // Implemented this way as there is no other way to do it currently (that I know :P)...
1569 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1570 {
1572 {
1573 m_damage = 0;
1574 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1575 return;
1576 }
1577 }
1578
1579 m_damage -= addhealth;
1580 }
1581}
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3791
@ SPELLFAMILY_DEATHKNIGHT
Definition SharedDefines.h:3799
@ AURA_STATE_SWIFTMEND
Definition SharedDefines.h:1318
@ SPELL_SCHOOL_MASK_HOLY
Definition SharedDefines.h:309
@ SPELL_AURA_PERIODIC_HEAL
Definition SpellAuraDefines.h:71
@ DOT
Definition Unit.h:257
SpellInfo const * GetSpellInfo() const
Definition SpellAuraEffects.h:54
uint32 GetId() const
Definition SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition SpellAuraEffects.h:47
Aura * GetBase() const
Definition SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition SpellAuraEffects.h:48
int32 GetAmount() const
Definition SpellAuraEffects.h:64
uint32 TargetAuraState
Definition SpellInfo.h:340
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:5620
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:1106

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3674{
3676 return;
3677
3678 if (!unitTarget || !unitTarget->IsAlive())
3679 return;
3680
3682 {
3684 return;
3685 }
3686
3687 int32 addhealth = 0;
3688
3689 // damage == 0 - heal for caster max health
3690 if (damage == 0)
3691 addhealth = m_caster->GetMaxHealth();
3692 else
3693 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3694
3695 m_healing += addhealth;
3696}
uint32 GetMaxHealth() const
Definition Unit.h:1094

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), GetSpellInfo(), Unit::HasUnitState(), Unit::IsAlive(), m_caster, m_healing, Unit::SendSpellDamageImmune(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1619{
1621 return;
1622
1623 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1624 return;
1625
1628
1629 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1630
1631 // xinef: handled in spell.cpp
1632 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1633
1634 m_damage += damage;
1635 // get max possible damage, don't count overkill for heal
1636 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1637
1638 //if (m_caster->IsAlive())
1639 //{
1640 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1641 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1642
1643 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1644 //}
1645}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:12002
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:11825

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4481{
4483 return;
4484
4485 if (!unitTarget)
4486 return;
4487
4488 Player* player = unitTarget->ToPlayer();
4489 if (!player)
4490 {
4491 return;
4492 }
4493
4494 uint8 currentDrunk = player->GetDrunkValue();
4495 int32 drunkMod = damage;
4496
4497 if (drunkMod == 0)
4498 return;
4499
4500 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4501 // In addition, we would not want currentDrunk to become more than 100.
4502 // So before adding the values, let's check that everything is fine.
4503 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4504 currentDrunk = 100;
4505 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4506 currentDrunk = 0;
4507 else
4508 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4509
4510 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4511
4512 if (currentDrunk == 100 && roll_chance_i(25))
4513 player->CastSpell(player, 67468, false); // Drunken Vomit
4514}
uint8 GetDrunkValue() const
Definition Player.h:2188
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:988

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
275{
277 return;
278
279 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
280 return;
281
282 if (unitTarget->IsPlayer())
284 return;
285
286 if (m_caster == unitTarget) // prevent interrupt message
287 finish();
288
289 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
290 data << m_caster->GetGUID();
291 data << unitTarget->GetGUID();
292 data << uint32(m_spellInfo->Id);
293 m_caster->SendMessageToSet(&data, true);
294
296}
@ CHEAT_GOD
Definition Player.h:996
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:308
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition Unit.cpp:824
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:845

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3699{
3701 return;
3702
3703 if (!unitTarget || !unitTarget->IsAlive())
3704 return;
3705
3707 // also exist case: apply cooldown to interrupted cast only and to all spells
3708 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3710 {
3712 {
3713 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3714 // check if we can interrupt spell
3715 if ((spell->getState() == SPELL_STATE_CASTING
3716 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3720 {
3721 if (m_originalCaster)
3722 {
3724 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3725 }
3726 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3728 }
3729 }
3730 }
3731}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:29
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:550
CurrentSpellTypes
Definition Unit.h:543
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:546
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:547
uint32 ChannelInterruptFlags
Definition SpellInfo.h:354
uint32 InterruptFlags
Definition SpellInfo.h:352
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5072
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4104
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:14970
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1569

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1070{
1072 return;
1073
1074 if (m_caster->IsInFlight())
1075 return;
1076
1077 if (!unitTarget)
1078 return;
1079
1080 float speedXY, speedZ;
1081 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1082 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1083
1084 if (m_caster->IsPlayer())
1085 {
1086 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1087 }
1088}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition MotionMaster.h:254
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition SpellEffects.cpp:1153
float GetExactDist2d(const float x, const float y) const
Definition Position.h:170

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1091{
1093 return;
1094
1095 if (m_caster->IsInFlight())
1096 return;
1097
1098 if (!m_targets.HasDst() || m_caster->GetVehicle())
1099 return;
1100
1101 // Init dest coordinates
1102 float x, y, z;
1103 destTarget->GetPosition(x, y, z);
1104 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1105 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1106 return;
1107
1108 float speedXY, speedZ;
1109 float dist = m_caster->GetExactDist2d(x, y);
1110 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1111
1112 // Override, calculations are incorrect
1113 if (m_spellInfo->Id == 49376) // feral charge
1114 {
1115 speedXY = pow(speedZ * 10, 8);
1117
1118 if (Player* player = m_caster->ToPlayer())
1119 {
1120 player->SetCanTeleport(true);
1121 }
1122
1123 if (m_caster->IsPlayer())
1124 {
1125 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1126 }
1127
1128 return;
1129 }
1130
1131 if (m_spellInfo->Id == 57604) // death grip
1132 {
1133 speedZ = 3.0f;
1134 speedXY = 50.0f;
1135 }
1136
1137 // crash fix?
1138 if (speedXY < 1.0f)
1139 speedXY = 1.0f;
1140
1141 if (Player* player = m_caster->ToPlayer())
1142 {
1143 player->SetCanTeleport(true);
1144 }
1145 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1146
1147 if (m_caster->IsPlayer())
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151}
#define INVALID_HEIGHT
Definition GridTerrainData.h:27
@ UNIT_FIELD_TARGET
Definition UpdateFields.h:92
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:326
bool IsValidMapCoord(float c)
Definition GridDefines.h:210

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5721{
5723 return;
5724
5725 if (!unitTarget)
5726 return;
5727
5729 if (!player)
5730 {
5731 return;
5732 }
5733
5734 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5735 if (!creatureEntry)
5736 {
5737 if (m_spellInfo->Id == 42793) // Burn Body
5738 creatureEntry = 24008; // Fallen Combatant
5739 }
5740
5741 if (creatureEntry)
5742 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5743}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:12743

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5707{
5709 return;
5710
5711 if (!unitTarget)
5712 return;
5713
5715 {
5716 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5717 }
5718}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4977{
4979 return;
4980
4981 if (!unitTarget)
4982 return;
4983
4984 // Xinef: allow entry specific spells to skip those checks
4985 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4986 {
4988 return;
4989
4990 if (unitTarget->GetVehicle())
4991 return;
4992
4993 if (Creature* creatureTarget = unitTarget->ToCreature())
4994 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4995 return;
4996 }
4997
4998 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5000 return;
5001
5002 // Instantly interrupt non melee spells being casted
5005
5006 float ratio = 0.1f;
5007 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5008 float speedz = float(damage) * ratio;
5009 if (speedxy <= 0.1f && speedz <= 0.1f)
5010 return;
5011
5012 float x, y;
5013 Unit* reflectionSource = m_reflectionTarget;
5014
5015 if (!reflectionSource && !m_reflectionTargetGuid.IsEmpty())
5016 {
5018 reflectionSource = resolvedSource;
5019 }
5020
5021 if (reflectionSource)
5022 {
5023 reflectionSource->GetPosition(x, y);
5024 }
5025 else if (!m_reflectionTargetGuid.IsEmpty())
5026 {
5029 }
5030 else if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5031 {
5032 if (m_targets.HasDst())
5033 destTarget->GetPosition(x, y);
5034 else
5035 return;
5036 }
5037 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5038 {
5039 m_caster->GetPosition(x, y);
5040 }
5041
5042 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5043
5044 if (unitTarget->IsPlayer())
5045 {
5046 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5047 }
5048}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition SharedDefines.h:933
@ CREATURE_TYPE_GIANT
Definition SharedDefines.h:2633
@ CREATURE_TYPE_BEAST
Definition SharedDefines.h:2629
bool IsEmpty() const
Definition ObjectGuid.h:161
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4176
uint32 GetCreatureType() const
Definition Unit.cpp:15301
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:19401

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), ObjectGuid::IsEmpty(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_reflectionTarget, m_reflectionTargetGuid, m_reflectionTargetPosition, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4703{
4705 return;
4706
4707 if (!unitTarget || unitTarget->IsInFlight())
4708 return;
4709
4710 if (!m_targets.HasDst())
4711 return;
4712
4713 Position dstpos = destTarget->GetPosition();
4715}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:19965

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5051{
5053 return;
5054
5055 if (!unitTarget)
5056 return;
5057
5058 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5059 float speedz = damage / 10.0f;
5060 //1891: Disengage
5062
5063 if (m_caster->IsPlayer())
5064 {
5065 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5066 }
5067
5068 // xinef: changes fall time
5069 if (m_caster->IsPlayer())
5071}
@ SPELLFAMILY_HUNTER
Definition SharedDefines.h:3793
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition Unit.cpp:19513

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3259{
3261 return;
3262
3263 if (!unitTarget)
3264 return;
3265
3266 if (unitTarget->ToPlayer())
3267 {
3268 EffectLearnSpell(effIndex);
3269 return;
3270 }
3271 Pet* pet = unitTarget->ToPet();
3272 if (!pet)
3273 return;
3274
3275 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3276 if (!learn_spellproto)
3277 return;
3278
3279 pet->learnSpell(learn_spellproto->Id);
3281 pet->GetOwner()->PetSpellInitialize();
3282}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1897
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2545

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2776{
2778 return;
2779
2780 if (!unitTarget->IsPlayer())
2781 return;
2782
2783 if (damage < 0)
2784 return;
2785
2786 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2787 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2788 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2789}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5508
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5322

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2546{
2548 return;
2549
2550 if (!unitTarget)
2551 return;
2552
2553 if (!unitTarget->IsPlayer())
2554 {
2555 if (unitTarget->ToPet())
2556 EffectLearnPetSpell(effIndex);
2557 return;
2558 }
2559
2560 Player* player = unitTarget->ToPlayer();
2561
2562 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2563 player->learnSpell(spellToLearn);
2564
2565 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2566 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2567}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3289
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3258

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5530{
5532 return;
5533
5534 if (!m_caster->IsPlayer())
5535 return;
5536
5537 Player* p_caster = m_caster->ToPlayer();
5539 return;
5540
5541 if (itemTarget->GetCount() < 5)
5542 return;
5543
5544 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5545 {
5546 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5547 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5548 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5549 }
5550
5552}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:51
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7799
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:768

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5363{
5365 return;
5366
5367 if (!unitTarget)
5368 return;
5369
5371}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition ThreatMgr.cpp:576
ThreatMgr & GetThreatMgr()
Definition Unit.h:943

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
239{
240 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
241}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2079{
2081 return;
2082
2083 if (!m_caster->IsPlayer())
2084 {
2085 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2086 return;
2087 }
2088
2089 Player* player = m_caster->ToPlayer();
2090
2091 uint32 lockId = 0;
2092 ObjectGuid guid;
2093
2094 // Get lockId
2095 if (gameObjTarget)
2096 {
2097 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2098 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2099 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2100 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2101 {
2102 //CanUseBattlegroundObject() already called in CheckCast()
2103 // in battleground check
2104 if (Battleground* bg = player->GetBattleground())
2105 {
2106 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2107 return;
2108 }
2109 }
2110 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2111 {
2112 //CanUseBattlegroundObject() already called in CheckCast()
2113 // in battleground check
2114 if (Battleground* bg = player->GetBattleground())
2115 {
2116 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2117 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2118 return;
2119 }
2120 }
2121 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2122 {
2125 {
2127 }
2128 return;
2129 }
2131 // handle outdoor pvp object opening, return true if go was registered for handling
2132 // these objects must have been spawned by outdoorpvp!
2133 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2134 return;
2135 lockId = goInfo->GetLockId();
2136 guid = gameObjTarget->GetGUID();
2137 }
2138 else if (itemTarget)
2139 {
2140 lockId = itemTarget->GetTemplate()->LockID;
2141 guid = itemTarget->GetGUID();
2142 }
2143 else
2144 {
2145 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2146 return;
2147 }
2148
2149 SkillType skillId = SKILL_NONE;
2150 int32 reqSkillValue = 0;
2151 int32 skillValue;
2152
2153 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2154 if (res != SPELL_CAST_OK)
2155 {
2156 SendCastResult(res);
2157 return;
2158 }
2159
2160 if (gameObjTarget)
2161 SendLoot(guid, LOOT_SKINNING);
2162 else if (itemTarget)
2163 {
2165 if (Player* itemOwner = itemTarget->GetOwner())
2166 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2167 }
2168
2169 // not allow use skill grow at item base open
2170 if (!m_CastItem && skillId != SKILL_NONE)
2171 {
2172 // update skill if really known
2173 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2174 {
2175 if (gameObjTarget)
2176 {
2177 // Allow one skill-up until respawned
2178 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2179 {
2181 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2182 }
2183
2184 }
2185 else if (itemTarget)
2186 {
2187 // Do one skill-up
2188 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2189 }
2190 }
2191 }
2193}
@ GO_JUST_DEACTIVATED
Definition GameObject.h:113
@ ITEM_FIELD_FLAG_UNLOCKED
Definition ItemTemplate.h:111
@ ITEM_CHANGED
Definition Item.h:210
@ LOOT_SKINNING
Definition LootMgr.h:85
#define sOutdoorPvPMgr
Definition OutdoorPvPMgr.h:102
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1595
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1581
@ BATTLEGROUND_EY
Definition SharedDefines.h:3743
@ ITEM_FIELD_FLAGS
Definition UpdateFields.h:42
Unit * GetOwner() const
Definition GameObject.cpp:1203
LootState getLootState() const
Definition GameObject.h:223
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2416
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.cpp:3048
void AddToSkillupList(ObjectGuid const &playerGuid)
Definition GameObject.cpp:3042
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:714
Definition Object.h:104
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:5087
void SendLoot(ObjectGuid guid, LootType loottype)
Definition SpellEffects.cpp:2012
Definition GameObjectData.h:31
uint32 GetAutoCloseTime() const
Definition GameObjectData.h:510
uint32 noDamageImmune
Definition GameObjectData.h:48
struct GameObjectTemplate::@235::@238 button
struct GameObjectTemplate::@235::@246 goober
uint32 losOK
Definition GameObjectData.h:64
uint32 GetLockId() const
Definition GameObjectData.h:427

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4685{
4687 return;
4688
4689 if (m_caster->IsPlayer())
4690 m_caster->ToPlayer()->SetCanParry(true);
4691}
void SetCanParry(bool value)
Definition Player.cpp:13146

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1845{
1847 return;
1848
1849 if (!m_spellAura)
1850 {
1852 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1853
1854 // Caster not in world, might be spell triggered from aura removal
1855 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1856 return;
1857 DynamicObject* dynObj = new DynamicObject();
1859 {
1860 delete dynObj;
1861 return;
1862 }
1863
1865 {
1866 m_spellAura = aura;
1869 }
1870 else
1871 return;
1872 }
1873
1876}
#define MAX_EFFECT_MASK
Definition DBCStructure.h:1638
@ DYNAMIC_OBJECT_AREA_SPELL
Definition DynamicObject.h:30
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition SpellAuras.cpp:291

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, DynamicObject, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6120{
6122 return;
6123
6124 if (!unitTarget)
6125 return;
6126
6127 Player* player = unitTarget->ToPlayer();
6128 if (!player)
6129 {
6130 return;
6131 }
6132
6133 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6134
6135 if (!sSoundEntriesStore.LookupEntry(soundid))
6136 {
6137 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6138 return;
6139 }
6140
6142}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6173{
6175 return;
6176
6177 if (!unitTarget)
6178 return;
6179
6180 Player* player = unitTarget->ToPlayer();
6181 if (!player)
6182 {
6183 return;
6184 }
6185
6186 switch (m_spellInfo->Id)
6187 {
6188 case 58730: // Restricted Flight Area
6189 case 58600: // Restricted Flight Area
6191 break;
6192 default:
6193 break;
6194 }
6195
6196 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6197
6198 if (!sSoundEntriesStore.LookupEntry(soundId))
6199 {
6200 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6201 return;
6202 }
6203
6204 player->PlayDirectSound(soundId, player);
6205}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:761
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:105
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:2927

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1431{
1433 return;
1434
1435 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1436 return;
1437
1438 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1439
1441 return;
1442
1443 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1444 if (m_spellInfo->Id == 8129)
1445 {
1448 damage = std::min(damage, maxDamage);
1449
1450 // Remove fear
1452 }
1453
1454 int32 power = damage;
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 if (PowerType == POWER_MANA)
1457 power -= unitTarget->GetSpellCritDamageReduction(power);
1458
1459 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1460
1461 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1462 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1463
1464 // add log data before multiplication (need power amount, not damage)
1465 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1466
1467 newDamage = int32(newDamage * dmgMultiplier);
1468
1469 m_damage += newDamage;
1470}
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:5056
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:14331
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1261

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1352{
1354 return;
1355
1356 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1357 return;
1358
1359 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1360
1362 return;
1363
1364 // add spell damage bonus
1367
1368 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1369 int32 power = damage;
1370 if (PowerType == POWER_MANA)
1371 power -= unitTarget->GetSpellCritDamageReduction(power);
1372
1373 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1374
1375 float gainMultiplier = 0.0f;
1376
1377 // Don`t restore from self drain
1378 if (m_caster != unitTarget)
1379 {
1380 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1381
1382 int32 gain = int32(newDamage * gainMultiplier);
1383
1385 }
1386 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1387}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2305{
2307 return;
2308
2309 if (!m_caster->IsPlayer())
2310 return;
2311 Player* p_target = m_caster->ToPlayer();
2312
2314 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2315 {
2316 p_target->AddWeaponProficiency(subClassMask);
2318 }
2319 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2320 {
2321 p_target->AddArmorProficiency(subClassMask);
2323 }
2324}
uint32 GetArmorProficiency() const
Definition Player.h:1379
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10078
uint32 GetWeaponProficiency() const
Definition Player.h:1378
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1377
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1376
int32 EquippedItemSubClassMask
Definition SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2688{
2690 EffectNULL(effIndex);
2691}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5136{
5138 return;
5139
5140 if (!unitTarget)
5141 return;
5142
5143 Position pos;
5144 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5145 {
5146 if (m_targets.HasDst())
5147 pos.Relocate(*destTarget);
5148 else
5149 return;
5150 }
5151 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5152 {
5153 // Xinef: Increase Z position a little bit, should protect from falling through textures
5155 }
5156
5157 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5158 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5159
5160 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5161
5162 if (unitTarget->IsPlayer())
5163 {
5164 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5165 }
5166}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition SharedDefines.h:934

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5074{
5076 return;
5077
5078 if (!unitTarget)
5079 return;
5080
5081 Player* player = unitTarget->ToPlayer();
5082 if (!player)
5083 {
5084 return;
5085 }
5086
5087 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5088
5089 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5090
5091 if (!quest)
5092 return;
5093
5094 // Player has never done this quest
5095 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5096 return;
5097
5098 // remove all quest entries for 'entry' from quest log
5099 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5100 {
5101 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5102 if (logQuest == quest_id)
5103 {
5104 player->SetQuestSlot(slot, 0);
5105
5106 // we ignore unequippable quest items in this case, it's still be equipped
5107 player->TakeQuestSourceItem(logQuest, false);
5108
5109 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5110 {
5111 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5112 player->UpdatePvPState();
5113 }
5114 }
5115 }
5116
5117 player->RemoveRewardedQuest(quest_id);
5118 player->RemoveActiveQuest(quest_id, false);
5119}
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:33
@ QUEST_STATUS_NONE
Definition QuestDef.h:100
bool HasPvPForcingQuest() const
Definition PlayerQuest.cpp:2527
void UpdatePvPState()
Definition PlayerUpdates.cpp:1439
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1502
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1506
PvPInfo pvpInfo
Definition Player.h:1861
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1397
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1527
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1462
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1545
Definition QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition QuestDef.h:221
bool IsHostile
Definition Player.h:348
bool IsInHostileArea
Definition Player.h:349

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4744{
4746 return;
4747
4748 if (!unitTarget)
4749 return;
4750
4751 Player* player = unitTarget->ToPlayer();
4752 if (!player)
4753 {
4754 return;
4755 }
4756
4757 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4758 if (questId)
4759 {
4760 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4761 if (!quest)
4762 return;
4763
4764 uint16 logSlot = player->FindQuestSlot(questId);
4765 if (logSlot < MAX_QUEST_LOG_SIZE)
4766 player->AreaExploredOrEventHappens(questId);
4767 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4768 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4769 }
4770}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1814
bool CanTakeQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition PlayerQuest.cpp:881
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1823

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, Player::SetRewardedQuest(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5746{
5748 return;
5749
5750 if (!unitTarget)
5751 return;
5752
5753 if (Player* player = unitTarget->ToPlayer())
5754 {
5755 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5756 }
5757}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5760{
5762 return;
5763
5764 if (!unitTarget)
5765 return;
5766
5767 Player* player = unitTarget->ToPlayer();
5768 if (!player)
5769 return;
5770
5771 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5772 {
5773 if (!player->CanTakeQuest(quest, false))
5774 return;
5775
5776 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5777 player->AddQuestAndCheckCompletion(quest, player);
5778
5779 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5780 }
5781}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:265
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition PlayerQuest.cpp:422
PlayerMenu * PlayerTalkClass
Definition Player.h:2272

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6262{
6264 return;
6265
6266 if (!unitTarget || !unitTarget->IsPlayer())
6267 return;
6268
6269 Player* player = m_caster->ToPlayer();
6270
6271 if (!player)
6272 return;
6273
6274 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6275
6276 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6277 if (!pProto)
6278 {
6279 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6280 return;
6281 }
6282
6283 if (Item* pItem = player->GetItemByEntry(item_id))
6284 {
6285 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6286 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6287 pItem->SetState(ITEM_CHANGED, player);
6288 }
6289}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5920{
5922 return;
5923
5924 if (unitTarget)
5926}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition Unit.h:950

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6208{
6210 return;
6211
6212 if (!unitTarget)
6213 return;
6214 // there may be need of specifying casterguid of removed auras
6215 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6216}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6108{
6110 return;
6111
6112 if (!unitTarget || !unitTarget->IsCreature() ||
6114 return;
6115
6117}
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:149
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:893
PetType getPetType() const
Definition Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4718{
4720 return;
4721
4722 if (!unitTarget)
4723 return;
4724
4725 Player* player = unitTarget->ToPlayer();
4726 if (!player)
4727 {
4728 return;
4729 }
4730
4731 float repChange = static_cast<float>(damage);
4732
4733 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4734
4735 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4736 if (!factionEntry)
4737 return;
4738
4739 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4740 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4741}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition SharedDefines.h:198
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition Player.cpp:5862
ReputationMgr & GetReputationMgr()
Definition Player.h:2142
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition ReputationMgr.h:117
Definition DBCStructure.h:907

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4636{
4638 return;
4639
4640 if (!unitTarget)
4641 return;
4642
4643 if (!unitTarget)
4644 return;
4645
4646 Player* target = unitTarget->ToPlayer();
4647 if (!target)
4648 {
4649 return;
4650 }
4651
4652 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4653 return;
4654
4655 if (target->isResurrectRequested()) // already have one active request
4656 return;
4657
4658 uint32 health = target->CountPctFromMaxHealth(damage);
4660
4661 ExecuteLogEffectResurrect(effIndex, target);
4662
4664 SendResurrectRequest(target);
4665}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1830
bool isResurrectRequested() const
Definition Player.h:1842
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5117
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5179

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5212{
5214 return;
5215
5216 if (damage < 0)
5217 return;
5218
5219 Player* player = m_caster->ToPlayer();
5220 if (!player)
5221 {
5222 return;
5223 }
5224
5225 Pet* pet = player->GetPet();
5226 if (!pet)
5227 {
5228 // Position passed to SummonPet is irrelevant with current implementation,
5229 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5230 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5231 return;
5232 }
5233
5235 if (pet->IsAlive())
5236 {
5237 return;
5238 }
5239
5240 // Reposition the pet's corpse before reviving so as not to grab aggro
5241 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5242 float x, y, z; // Will be used later to reposition the pet if we have one
5243 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5244 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5245 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5249 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5251 pet->SetDisplayId(pet->GetNativeDisplayId());
5252
5253 // xinef: restore movement
5254 if (auto ci = pet->GetCharmInfo())
5255 {
5256 ci->SetIsAtStay(false);
5257 ci->SetIsFollowing(false);
5258 }
5259
5261}
constexpr float PET_FOLLOW_DIST
Definition PetDefines.h:206
@ SUMMON_PET
Definition PetDefines.h:32
@ UNIT_DYNFLAG_NONE
Definition SharedDefines.h:3360
@ UNIT_STATE_POSSESSED
Definition UnitDefines.h:186
@ UNIT_STATE_ALL_STATE
Definition UnitDefines.h:224
float GetFollowAngle() const override
Definition TemporarySummon.h:93
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition Pet.cpp:626
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition Pet.cpp:2406
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0ms, uint32 healthPct=0)
Definition Player.cpp:8970
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:759
void SetHealth(uint32 val)
Definition Unit.cpp:15722
uint32 GetNativeDisplayId() const
Definition Unit.h:1955
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:739
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition Object.cpp:2736

References Alive, Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4020{
4022 return;
4023
4024 if (!unitTarget)
4025 return;
4026
4028 {
4030 // Xinef: replaced with CombatStop(false)
4033
4034 // Night Elf: Shadowmeld only resets threat temporarily
4035 if (m_spellInfo->Id != 59646)
4037
4038 if (unitTarget->IsPlayer())
4039 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4040 }
4041 else
4042 {
4043 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4044 unitTarget->CombatStop(true);
4045 }
4046
4047 UnitList targets;
4048 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4051 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4052 {
4053 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4054 continue;
4055
4057 {
4058 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4059 {
4060 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4061 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4062 {
4063 Creature* c = (*iter)->ToCreature();
4064 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4065 continue;
4066 }
4067 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4068 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4069 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4070 {
4071 // at least one effect truly targets an unit, interrupt the spell
4072 interrupt = true;
4073 break;
4074 }
4075 if (interrupt)
4076 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4077 }
4078 }
4079 }
4080
4081 // Xinef: Set last sanctuary time
4083}
#define CURRENT_MAX_SPELL
Definition Unit.h:551
void UpdateVisibility(bool checkThreat)
Definition HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition HostileRefMgr.cpp:85
virtual bool IsEncounterInProgress() const
Definition InstanceScript.cpp:137
void SendAttackSwingCancelAttack()
Definition PlayerMisc.cpp:141
void CombatStop(bool includingCast=false)
Definition Unit.cpp:10646
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition Unit.cpp:10694
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:10613

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
324{
326 return;
327
328 if (unitTarget && unitTarget->IsAlive())
329 {
330 bool apply_direct_bonus = true;
332 {
334 {
335 // Meteor like spells (divided damage to targets)
337 {
338 uint32 count = 0;
339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
340 if (ihit->effectMask & (1 << effIndex))
341 ++count;
342
343 damage /= count; // divide to all targets
344 }
345 break;
346 }
348 {
349 // Shield Slam
350 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
351 {
352 uint8 level = m_caster->GetLevel();
353 // xinef: shield block should increase the limit
354 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
355 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
356
357 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
358 }
359 // Victory Rush
360 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
362 // Shockwave
363 else if (m_spellInfo->Id == 46968)
364 {
366 if (pct > 0)
368 break;
369 }
370 break;
371 }
373 {
374 // Incinerate Rank 1 & 2
375 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
376 {
377 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
378 // Check aura state for speed but aura state set not only for Immolate spell
380 {
382 damage += damage / 4;
383 }
384 }
385 // Conflagrate - consumes Immolate or Shadowflame
387 {
388 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
389
391 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
392 {
393 // for caster applied auras only
394 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
395 (*i)->GetCasterGUID() != m_caster->GetGUID())
396 continue;
397
398 // Immolate
399 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
400 {
401 aura = *i; // it selected always if exist
402 break;
403 }
404
405 // Shadowflame
406 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
407 aura = *i; // remember but wait possible Immolate as primary priority
408 }
409
410 // found Immolate or Shadowflame
411 if (aura)
412 {
413 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
414 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
415 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
416 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
417
418 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
419
420 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
422
423 apply_direct_bonus = false;
424 // Glyph of Conflagrate
425 if (!m_caster->HasAura(56235))
427
428 break;
429 }
430 }
431 // Shadow Bite
432 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
433 {
434 if (m_caster->IsCreature() && m_caster->IsPet())
435 {
436 if (Player* owner = m_caster->GetOwner()->ToPlayer())
437 {
438 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
439 {
440 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
441 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
442 }
443 }
444 }
445 }
446 break;
447 }
449 {
450 // Improved Mind Blast (Mind Blast in shadow form bonus)
451 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
452 {
454 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
455 {
456 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
457 ((*i)->GetSpellInfo()->SpellIconID == 95))
458 {
459 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
460 if (roll_chance_i(chance))
461 // Mind Trauma
462 m_caster->CastSpell(unitTarget, 48301, true, 0);
463 break;
464 }
465 }
466 }
467 break;
468 }
470 {
471 // Ferocious Bite
472 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
473 {
474 // converts each extra point of energy into ($f1+$AP/410) additional damage
476 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
477 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
478 damage += int32(energy * multiple);
480 }
481 // Wrath
482 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
483 {
484 // Improved Insect Swarm
485 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
487 AddPct(damage, aurEff->GetAmount());
488 }
489 break;
490 }
492 {
493 // Envenom
494 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
495 {
496 if (Player* player = m_caster->ToPlayer())
497 {
498 // consume from stack dozes not more that have combo-points
499 if (uint32 combo = player->GetComboPoints())
500 {
501 // Lookup for Deadly poison (only attacker applied)
503 {
504 // count consumed deadly poison doses at target
505 bool needConsume = true;
506 uint32 spellId = aurEff->GetId();
507
508 uint32 doses = aurEff->GetBase()->GetStackAmount();
509 if (doses > combo)
510 doses = combo;
511
512 // Master Poisoner
513 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
514 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
515 {
516 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
517 {
518 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
519
520 if (chance && roll_chance_i(chance))
521 needConsume = false;
522
523 break;
524 }
525 }
526
527 if (needConsume)
528 for (uint32 i = 0; i < doses; ++i)
530
531 damage *= doses;
532 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
533 }
534
535 // Eviscerate and Envenom Bonus Damage (item set effect)
536 if (m_caster->HasAura(37169))
537 damage += combo * 40;
538 }
539 }
540 }
541 // Eviscerate
542 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
543 {
544 if (m_caster->IsPlayer())
545 {
546 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
547 {
549 damage += int32(ap * combo * 0.07f);
550
551 // Eviscerate and Envenom Bonus Damage (item set effect)
552 if (m_caster->HasAura(37169))
553 damage += combo * 40;
554 }
555 }
556 }
557 break;
558 }
560 {
561 //Gore
562 if (m_spellInfo->SpellIconID == 1578)
563 {
564 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
565 damage *= 2;
566 }
567 // Steady Shot
568 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
569 {
570 bool found = false;
571 // check dazed affect
573 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
574 {
575 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
576 {
577 found = true;
578 break;
579 }
580 }
581
583 if (found)
584 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
585
586 if (Player* caster = m_caster->ToPlayer())
587 {
588 // Add Ammo and Weapon damage plus RAP * 0.1
589 float dmg_min = 0.f;
590 float dmg_max = 0.f;
591 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
592 {
593 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
594 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
595 }
596
597 if (dmg_max == 0.0f && dmg_min > dmg_max)
598 {
599 damage += int32(dmg_min);
600 }
601 else
602 {
603 damage += irand(int32(dmg_min), int32(dmg_max));
604 }
605 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
606 }
607 }
608 break;
609 }
611 {
612 // Hammer of the Righteous
613 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
614 {
615 // Add main hand dps * effect[2] amount
616 if (Player* player = m_caster->ToPlayer())
617 {
618 float minTotal = 0.f;
619 float maxTotal = 0.f;
620 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
621 {
622 float tmpMin, tmpMax;
623 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
624 minTotal += tmpMin;
625 maxTotal += tmpMax;
626 }
627
628 float average = (minTotal + maxTotal) / 2;
631 }
632 break;
633 }
634 // Shield of Righteousness
635 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
636 {
637 uint8 level = m_caster->GetLevel();
638 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
639 if (m_caster->GetAuraEffect(64882, EFFECT_0))
640 block_value += 225;
641 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
642 break;
643 }
644 break;
645 }
646 }
647
648 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
649 {
650 // Xinef: protection
651 if (damage < 0)
652 damage = 0;
653
656 }
657
658 m_damage += damage;
659 }
660}
#define MAX_ITEM_PROTO_DAMAGES
Definition ItemTemplate.h:613
@ EFFECT_2
Definition SharedDefines.h:33
@ POWER_ENERGY
Definition SharedDefines.h:283
@ SPELLFAMILY_PRIEST
Definition SharedDefines.h:3790
@ AURA_STATE_CONFLAGRATE
Definition SharedDefines.h:1317
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:179
@ FORM_SHADOW
Definition UnitDefines.h:95
@ MINDAMAGE
Definition Unit.h:142
@ MAXDAMAGE
Definition Unit.h:143
uint8 GetStackAmount() const
Definition SpellAuras.h:148
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition Unit.cpp:15672
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:14943
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5044
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.h:904
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition Unit.h:1422

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3784{
3786 return;
3787
3789
3791 {
3793 {
3794 switch (m_spellInfo->Id)
3795 {
3796 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3797 case 22539:
3798 case 22972:
3799 case 22975:
3800 case 22976:
3801 case 22977:
3802 case 22978:
3803 case 22979:
3804 case 22980:
3805 case 22981:
3806 case 22982:
3807 case 22983:
3808 case 22984:
3809 case 22985:
3810 {
3811 if (!unitTarget || !unitTarget->IsAlive())
3812 return;
3813
3814 // Onyxia Scale Cloak
3815 if (unitTarget->HasAura(22683))
3816 return;
3817
3818 // Shadow Flame
3819 m_caster->CastSpell(unitTarget, 22682, true);
3820 return;
3821 }
3822 // Plant Warmaul Ogre Banner
3823 case 32307:
3824 if (Player* caster = m_caster->ToPlayer())
3825 {
3826 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3827 if (Creature* target = unitTarget->ToCreature())
3828 {
3829 target->setDeathState(DeathState::Corpse);
3830 target->RemoveCorpse();
3831 }
3832 }
3833 break;
3834 // SOTA defender teleport
3835 case 54640:
3836 {
3837 if (Player* player = unitTarget->ToPlayer())
3838 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3839 {
3840 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3841 {
3842 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3843 bg->DefendersPortalTeleport(dportal, player);
3844 }
3845 }
3846 return;
3847 }
3848 /*// Mug Transformation
3849 case 41931:
3850 {
3851 if (!m_caster->IsPlayer())
3852 return;
3853
3854 uint8 bag = 19;
3855 uint8 slot = 0;
3856 Item* item = nullptr;
3857
3858 while (bag) // 256 = 0 due to var type
3859 {
3860 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3861 if (item && item->GetEntry() == 38587)
3862 break;
3863
3864 ++slot;
3865 if (slot == 39)
3866 {
3867 slot = 0;
3868 ++bag;
3869 }
3870 }
3871 if (bag)
3872 {
3873 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3874 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3875 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3876 m_caster->CastSpell(m_caster, 42518, true);
3877 return;
3878 }
3879 break;
3880 }*/
3881 // Roll Dice - Decahedral Dwarven Dice
3882 case 47770:
3883 {
3884 char buf[128];
3885 const char* gender = "his";
3886 if (m_caster->getGender() > 0)
3887 gender = "her";
3888 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3889 m_caster->TextEmote(buf);
3890 break;
3891 }
3892 case 52173: // Coyote Spirit Despawn
3893 case 60243: // Blood Parrot Despawn
3896 return;
3897 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3898 {
3900 return;
3901
3903
3904 return;
3905 }
3906 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3907 {
3908 if (!m_caster->IsPlayer())
3909 return;
3910
3911 // Delete item from inventory at death
3913
3914 return;
3915 }
3916 case 58418: // Portal to Orgrimmar
3917 case 58420: // Portal to Stormwind
3918 {
3919 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3920 return;
3921
3922 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3923 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3924
3926 unitTarget->CastSpell(unitTarget, spellID, true);
3927
3928 return;
3929 }
3930 // Stoneclaw Totem
3931 case 55328: // Rank 1
3932 case 55329: // Rank 2
3933 case 55330: // Rank 3
3934 case 55332: // Rank 4
3935 case 55333: // Rank 5
3936 case 55335: // Rank 6
3937 case 55278: // Rank 7
3938 case 58589: // Rank 8
3939 case 58590: // Rank 9
3940 case 58591: // Rank 10
3941 {
3942 int32 basepoints0 = damage;
3943 // Cast Absorb on totems
3944 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
3945 {
3946 if (!unitTarget->m_SummonSlot[slot])
3947 continue;
3948
3950 if (totem && totem->IsTotem())
3951 {
3952 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3953 }
3954 }
3955 // Glyph of Stoneclaw Totem
3956 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3957 {
3958 basepoints0 *= aur->GetAmount();
3959 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3960 }
3961 break;
3962 }
3963 case 61263: // for item Intravenous Healing Potion (44698)
3964 {
3965 if (!m_caster || !unitTarget)
3966 return;
3967
3968 m_caster->CastSpell(m_caster, 61267, true);
3969 m_caster->CastSpell(m_caster, 61268, true);
3970 return;
3971 }
3972 }
3973 break;
3974 }
3975 case SPELLFAMILY_ROGUE:
3976 {
3977 switch (m_spellInfo->Id)
3978 {
3979 // Master of Subtlety
3980 case 31666:
3981 {
3982 if (!unitTarget)
3983 return;
3984
3985 Aura* mos = unitTarget->GetAura(31665);
3986 if (mos)
3987 {
3988 mos->SetMaxDuration(6000);
3989 mos->SetDuration(6000, true);
3990 }
3991
3992 break;
3993 }
3994 // Overkill
3995 case 58428:
3996 {
3997 if (!unitTarget)
3998 return;
3999
4000 Aura* overkill = unitTarget->GetAura(58427);
4001 if (overkill)
4002 {
4003 overkill->SetMaxDuration(20000);
4004 overkill->SetDuration(20000, true);
4005 }
4006
4007 break;
4008 }
4009 }
4010 break;
4011 }
4012 }
4013
4014 // normal DB scripted effect
4015 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4017}
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:101
@ BATTLEGROUND_SA
Definition SharedDefines.h:3745
Class for manage Strand of Ancient battleground.
Definition BattlegroundSA.h:428
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition BattlegroundSA.cpp:592
void DespawnOrUnsummon(Milliseconds msTimeToDespawn=0ms, Seconds forcedRespawnTimer=0s)
Definition Creature.cpp:2130
virtual void UnSummon(Milliseconds msTime=0ms)
Definition TemporarySummon.cpp:292
uint8 getGender() const
Definition Unit.h:838
bool IsSummon() const
Definition Unit.h:784
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition Unit.cpp:21252
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition Object.cpp:2478
std::string const & GetName() const
Definition Object.h:524

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), Corpse, damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM_FIRE, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4846{
4848 return;
4849
4850 if (!m_caster || m_caster->IsAlive())
4851 return;
4852 if (!m_caster->IsPlayer())
4853 return;
4854 if (!m_caster->IsInWorld())
4855 return;
4856
4857 uint32 health = 0;
4858 uint32 mana = 0;
4859
4860 // flat case
4861 if (damage < 0)
4862 {
4863 health = uint32(-damage);
4864 mana = m_spellInfo->Effects[effIndex].MiscValue;
4865 }
4866 // percent case
4867 else
4868 {
4872 }
4873
4874 Player* player = m_caster->ToPlayer();
4875 player->ResurrectPlayer(0.0f);
4876
4877 player->SetHealth(health);
4878 player->SetPower(POWER_MANA, mana);
4879 player->SetPower(POWER_RAGE, 0);
4880 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4881
4882 player->SpawnCorpseBones();
4883}
@ POWER_RAGE
Definition SharedDefines.h:281
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4600
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4382
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:15810

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1390{
1391 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1394 return;
1395
1396 WorldObject* target = nullptr;
1397
1398 // call events for object target if present
1400 {
1401 if (unitTarget)
1402 target = unitTarget;
1403 else if (gameObjTarget)
1404 target = gameObjTarget;
1405 }
1406 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1407 {
1408 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1409 // this check was requested by scripters, but it has some downsides:
1410 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1411 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1412 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1413 return;
1414 // some spells have no target entries in dbc and they use focus target
1415 if (focusObject)
1416 target = focusObject;
1418 }
1419
1420 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1421
1422 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1423 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1424 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1425 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1426
1427 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1428}
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:60
@ TARGET_FLAG_UNIT_MASK
Definition SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition SpellInfo.h:70
Definition Object.h:471
ZoneScript * GetZoneScript() const
Definition Object.h:626
Definition ZoneScript.h:26

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5122{
5124 return;
5125
5126 if (!unitTarget)
5127 return;
5128
5129 if (Player* player = unitTarget->ToPlayer())
5130 {
5131 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5132 }
5133}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5555{
5557 return;
5558
5559 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5560}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4886{
4888 return;
4889
4890 if (!unitTarget->IsCreature())
4891 return;
4892 if (!m_caster->IsPlayer())
4893 return;
4894
4895 Creature* creature = unitTarget->ToCreature();
4896 int32 targetLevel = creature->GetLevel();
4897
4898 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4899
4903
4904 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4905
4906 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4907
4908 // Double chances for elites
4909 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4910}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3361
bool isElite() const
Definition Creature.h:115
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:124

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5586{
5588 return;
5589
5590 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5591 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5592 return;
5593
5595
5596 // We have a corpse object as the target.
5597 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5599}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7760
void RemoveObjectTarget()
Definition Spell.cpp:320

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_targets, Player::RemovedInsignia(), SpellCastTargets::RemoveObjectTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6145{
6147 return;
6148
6149 if (!unitTarget)
6150 return;
6151
6152 if (Player* player = unitTarget->ToPlayer())
6153 {
6154 player->UpdateSpecCount(damage);
6155 }
6156}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5567{
5569 return;
5570
5571 /*
5572 if (!unitTarget->IsPlayer())
5573 return;
5574 if (!unitTarget->IsInWorld())
5575 return;
5576
5577 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5578 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5579 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5580 unitTarget->ToPlayer()->SpawnCorpseBones();
5581 */
5582}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5602{
5604 return;
5605
5606 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5607
5608 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5609 return;
5610
5611 DispelChargesList steal_list;
5612
5613 // Create dispel mask by dispel type
5614 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5615 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5616 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5617 {
5618 Aura* aura = itr->second;
5620 if (!aurApp)
5621 continue;
5622
5623 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5624 {
5625 // Need check for passive? this
5626 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5627 continue;
5628
5629 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5630 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5631 // Polymorph instead of 1 / (5 + 1) -> 16%.
5632 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5633 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5634 if (charges > 0)
5635 steal_list.push_back(std::make_pair(aura, charges));
5636 }
5637 }
5638
5639 if (steal_list.empty())
5640 return;
5641
5642 // Ok if exist some buffs for dispel try dispel it
5643 uint32 failCount = 0;
5644 DispelList success_list;
5645 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5646 // dispel N = damage buffs (or while exist buffs for dispel)
5647 for (int32 count = 0; count < damage && !steal_list.empty();)
5648 {
5649 // Random select buff for dispel
5650 DispelChargesList::iterator itr = steal_list.begin();
5651 std::advance(itr, urand(0, steal_list.size() - 1));
5652
5653 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5654 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5655 if (!chance)
5656 {
5657 steal_list.erase(itr);
5658 continue;
5659 }
5660 else
5661 {
5662 if (roll_chance_i(chance))
5663 {
5664 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5665 --itr->second;
5666 if (itr->second <= 0)
5667 steal_list.erase(itr);
5668 }
5669 else
5670 {
5671 if (!failCount)
5672 {
5673 // Failed to dispell
5674 dataFail << m_caster->GetGUID(); // Caster GUID
5675 dataFail << unitTarget->GetGUID(); // Victim GUID
5676 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5677 }
5678 ++failCount;
5679 dataFail << uint32(itr->first->GetId()); // Spell Id
5680 }
5681 ++count;
5682 }
5683 }
5684
5685 if (failCount)
5686 m_caster->SendMessageToSet(&dataFail, true);
5687
5688 if (success_list.empty())
5689 return;
5690
5691 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5692 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5693 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5694 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5695 dataSuccess << uint8(0); // not used
5696 dataSuccess << uint32(success_list.size()); // count
5697 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5698 {
5699 dataSuccess << uint32(itr->first); // Spell Id
5700 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5701 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5702 }
5703 m_caster->SendMessageToSet(&dataSuccess, true);
5704}
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition SharedDefines.h:662
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition SharedDefines.h:547
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition SpellEffects.cpp:2569
bool IsPositive() const
Definition SpellAuras.h:68
uint8 GetCharges() const
Definition SpellAuras.h:141
bool IsPassive() const
Definition SpellAuras.cpp:1034
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition Unit.cpp:5125
@ SMSG_SPELLSTEALLOG
Definition Opcodes.h:849

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4177{
4179 return;
4180
4181 if (!m_caster->IsPlayer())
4182 return;
4183
4184 Player* target = m_caster->ToPlayer();
4185 if (target->IsInFlight())
4186 return;
4187
4188 // xinef: if player is dead - teleport to graveyard
4189 if (!target->IsAlive())
4190 {
4191 if (target->HasPreventResurectionAura())
4192 return;
4193
4194 // xinef: player is in corpse
4195 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4196 target->BuildPlayerRepop();
4197 target->RepopAtGraveyard();
4198 return;
4199 }
4200
4201 // xinef: no hearthstone in bag or on cooldown
4202 Item* hearthStone = target->GetItemByEntry(6948);
4203 if (!hearthStone || target->HasSpellCooldown(8690))
4204 {
4205 float o = rand_norm() * 2 * M_PI;
4206 Position pos = *target;
4207 target->MovePositionToFirstCollision(pos, 5.0f, o);
4208 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4209 return;
4210 }
4211
4212 // xinef: we have hearthstone not on cooldown, just use it
4214}
@ PLAYER_FLAGS_GHOST
Definition Player.h:464
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:4832
void BuildPlayerRepop()
Definition Player.cpp:4334
bool HasPreventResurectionAura() const
Definition Unit.h:1787
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2895

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::HasPlayerFlag(), Unit::HasPreventResurectionAura(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2196{
2198 return;
2199
2200 if (!m_caster->IsPlayer())
2201 return;
2202
2203 Player* player = m_caster->ToPlayer();
2204
2205 // applied only to using item
2206 if (!m_CastItem)
2207 return;
2208
2209 // ... only to item in own inventory/bank/equip_slot
2210 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2211 return;
2212
2213 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2214 if (!newitemid)
2215 return;
2216
2217 uint16 pos = m_CastItem->GetPos();
2218
2219 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2220 if (!pNewItem)
2221 return;
2222
2223 // Client-side enchantment durations update
2225
2229
2231 {
2233 player->DurabilityLoss(pNewItem, lossPercent);
2234 }
2235
2236 if (player->IsInventoryPos(pos))
2237 {
2238 ItemPosCountVec dest;
2239 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2240 if (msg == EQUIP_ERR_OK)
2241 {
2242 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2243
2244 // prevent crash at access and unexpected charges counting with item update queue corrupt
2246 m_targets.SetItemTarget(nullptr);
2247
2248 m_CastItem = nullptr;
2250
2251 player->StoreItem(dest, pNewItem, true);
2252 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2253 return;
2254 }
2255 }
2256 else if (player->IsBankPos(pos))
2257 {
2258 ItemPosCountVec dest;
2259 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2260 if (msg == EQUIP_ERR_OK)
2261 {
2262 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2263
2264 // prevent crash at access and unexpected charges counting with item update queue corrupt
2266 m_targets.SetItemTarget(nullptr);
2267
2268 m_CastItem = nullptr;
2270
2271 player->BankItem(dest, pNewItem, true);
2272 return;
2273 }
2274 }
2275 else if (player->IsEquipmentPos(pos))
2276 {
2277 uint16 dest;
2278
2279 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2280
2281 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2282
2283 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2284 {
2286
2287 // prevent crash at access and unexpected charges counting with item update queue corrupt
2289 m_targets.SetItemTarget(nullptr);
2290
2291 m_CastItem = nullptr;
2293
2294 player->EquipItem(dest, pNewItem, true);
2295 player->AutoUnequipOffhandIfNeed();
2296 return;
2297 }
2298 }
2299
2300 // fail
2301 delete pNewItem;
2302}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition Item.h:86
@ ITEM_FIELD_DURABILITY
Definition UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition UpdateFields.h:70
uint8 GetSlot() const
Definition Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition Item.cpp:1087
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:305
uint16 GetPos() const
Definition Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:306
uint8 GetBagSlot() const
Definition Item.cpp:784
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1278
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1872
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1352
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1303
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4796
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2651
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3089
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1276
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12475
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2798
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2104
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1867
static bool IsBankPos(uint16 pos)
Definition Player.h:1281

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4564{
4566 return;
4567
4568 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4569
4570 uint8 slot = 0;
4571 switch (m_spellInfo->Effects[effIndex].Effect)
4572 {
4574 slot = 0;
4575 break;
4577 slot = 1;
4578 break;
4580 slot = 2;
4581 break;
4583 slot = 3;
4584 break;
4585 default:
4586 return;
4587 }
4588
4589 if (m_caster)
4590 {
4591 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4592 if (guid)
4593 {
4594 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4595 {
4596 // Recast case - null spell id to make auras not be removed on object remove from world
4597 if (m_spellInfo->Id == gameObject->GetSpellId())
4598 gameObject->SetSpellId(0);
4599 m_caster->RemoveGameObject(gameObject, true);
4600 }
4601 m_caster->m_ObjectSlot[slot].Clear();
4602 }
4603 }
4604
4605 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4606
4607 float x, y, z;
4608 // If dest location if present
4609 if (m_targets.HasDst())
4610 destTarget->GetPosition(x, y, z);
4611 // Summon in random point all other units if location present
4612 else
4614
4615 Map* map = m_caster->GetMap();
4616 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4617 {
4618 delete pGameObj;
4619 return;
4620 }
4621
4622 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4623 int32 duration = m_spellInfo->GetDuration();
4624 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4625 pGameObj->SetSpellId(m_spellInfo->Id);
4626 m_caster->AddGameObject(pGameObj);
4627
4628 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4629
4630 map->AddToMap(pGameObj, true);
4631
4632 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4633}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition ObjectDefines.h:44
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition SharedDefines.h:896
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition SharedDefines.h:893
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition SharedDefines.h:895
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition SharedDefines.h:894
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition Unit.h:2062

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), GameObject, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3734{
3736 return;
3737
3738 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3739
3740 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3741
3742 WorldObject* target = focusObject;
3743 if (!target)
3744 target = m_caster;
3745
3746 float x, y, z;
3747 if (m_targets.HasDst())
3748 destTarget->GetPosition(x, y, z);
3749 else
3751
3752 Map* map = target->GetMap();
3753
3754 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3755 {
3756 delete pGameObj;
3757 return;
3758 }
3759
3760 int32 duration = m_spellInfo->GetDuration();
3761
3762 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3763 pGameObj->SetSpellId(m_spellInfo->Id);
3764
3765 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3766
3767 // Wild object not have owner and check clickable by players
3768 map->AddToMap(pGameObj, true);
3769
3770 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3771 if (Player* player = m_caster->ToPlayer())
3772 if (Battleground* bg = player->GetBattleground())
3773 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3774
3775 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3776 {
3777 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3778 linkedTrap->SetSpellId(m_spellInfo->Id);
3779 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3780 }
3781}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1597
@ TEAM_ALLIANCE
Definition SharedDefines.h:771
@ TEAM_HORDE
Definition SharedDefines.h:772
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2709
GameobjectTypes GetGoType() const
Definition GameObject.h:202

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GameObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3145{
3147 return;
3148
3149 if (!m_originalCaster)
3150 return;
3151
3152 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3153 int32 duration = m_spellInfo->GetDuration();
3154
3155 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3156 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3157
3158 Player* owner = m_originalCaster->ToPlayer();
3159 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3161
3162 if (!owner)
3163 {
3164 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3165 if (properties)
3166 {
3167 // Xinef: unsummon old guardian
3168 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3169 oldPet->UnSummon();
3170 SummonGuardian(effIndex, petentry, properties, 1, false);
3171 }
3172 return;
3173 }
3174
3175 Pet* OldSummon = owner->GetPet();
3176
3177 // if pet requested type already exist
3178 if (OldSummon)
3179 {
3180 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3181 {
3182 // pet in corpse state can't be summoned
3183 if (OldSummon->isDead())
3184 return;
3185
3186 ASSERT(OldSummon->GetMap() == owner->GetMap());
3187
3188 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3189
3190 float px, py, pz;
3191 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3192
3193 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3194 OldSummon->UpdateObjectVisibility();
3195
3196 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3197 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3198 // notify player
3199 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3200 owner->SendClearCooldown(itr->first, OldSummon);
3201
3202 // actually clear cooldowns
3203 OldSummon->m_CreatureSpellCooldowns.clear();
3204 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3205 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3206 {
3207 Aura const* aura = i->second->GetBase();
3208 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3209 OldSummon->RemoveAura(i);
3210 else
3211 ++i;
3212 }
3213 return;
3214 }
3215
3216 if (owner->IsPlayer())
3217 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3218 else
3219 return;
3220 }
3221
3222 float x, y, z;
3223 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3224 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3225 if (!pet)
3226 return;
3227
3228 if (m_caster->IsCreature())
3229 {
3230 if (m_caster->ToCreature()->IsTotem())
3232 else
3234 }
3235
3237
3238 // Reset cooldowns
3240 {
3241 pet->m_CreatureSpellCooldowns.clear();
3242 owner->PetSpellInitialize();
3243 }
3244
3245 // Set health to max if new pet is summoned
3246 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3247 // pet should have full health
3248 pet->SetHealth(pet->GetMaxHealth());
3249
3250 // generate new name for summon pet
3251 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3252 if (!new_name.empty())
3253 pet->SetName(new_name);
3254
3255 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3256}
@ SPELLMOD_DURATION
Definition SpellDefines.h:77
@ REACT_DEFENSIVE
Definition Unit.h:556
@ REACT_AGGRESSIVE
Definition Unit.h:557
bool CanBeSentToClient() const
Definition SpellAuras.cpp:1089
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition Creature.h:253
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:99
Definition TemporarySummon.h:106
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:14756
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:5970
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:17589
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:19388
Powers getPowerType() const
Definition Unit.h:1116
bool isDead() const
Definition Unit.h:1775
void SetName(std::string const &newname)
Definition Object.h:525
float GetObjectSize() const
Definition Object.cpp:2808

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4217{
4218 // workaround - this effect should not use target map
4220 return;
4221
4222 if (!unitTarget)
4223 return;
4224
4225 Player* player = unitTarget->ToPlayer();
4226 if (!player)
4227 {
4228 return;
4229 }
4230
4231 // Evil Twin (ignore player summon, but hide this for summoner)
4232 // Xinef: Unit Target may be on other map!!!, Need workaround
4233 if (unitTarget->HasAura(23445))
4234 return;
4235
4236 float x, y, z;
4237 m_caster->GetPosition(x, y, z);
4238
4239 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4240
4241 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4242 data << m_caster->GetGUID(); // summoner guid
4243 data << uint32(m_caster->GetZoneId()); // summoner zone
4244 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4245 player->SendDirectMessage(&data);
4246}
#define MAX_PLAYER_SUMMON_DELAY
Definition Player.h:923
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition Player.cpp:16331
@ SMSG_SUMMON_REQUEST
Definition Opcodes.h:713

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, Player::SendDirectMessage(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6339{
6341 return;
6342
6343 if (!m_caster->IsPlayer())
6344 return;
6345
6346 if (!unitTarget)
6347 return;
6348
6349 Player* player = unitTarget->ToPlayer();
6350 if (!player)
6351 {
6352 return;
6353 }
6354
6355 float x, y, z;
6356 m_caster->GetPosition(x, y, z);
6358 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6359 data << m_caster->GetGUID();
6360 data << uint32(m_caster->GetZoneId());
6361 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6362 player->SendDirectMessage(&data);
6363}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, Player::SendDirectMessage(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2327{
2329 return;
2330
2331 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2332
2333 if (m_spellValue->MiscVal[effIndex])
2334 entry = m_spellValue->MiscVal[effIndex];
2335
2336 if (!entry)
2337 return;
2338
2339 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2340 if (!properties)
2341 {
2342 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2343 return;
2344 }
2345
2346 if (!m_originalCaster)
2347 return;
2348
2349 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2350 int32 duration = m_spellInfo->GetDuration();
2351 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2352 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2353
2354 TempSummon* summon = nullptr;
2355
2356 // determine how many units should be summoned
2357 uint32 numSummons;
2358
2359 // some spells need to summon many units, for those spells number of summons is stored in effect value
2360 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2361 // and in spell attributes, possibly we need to add a table for those)
2362 // so here's a list of MiscValueB values, which is currently most generic check
2363 switch (properties->Id)
2364 {
2365 case 64:
2366 case 61:
2367 case 1101:
2368 case 66:
2369 case 648:
2370 case 2301:
2371 case 1061:
2372 case 1261:
2373 case 629:
2374 case 181:
2375 case 715:
2376 case 1562:
2377 case 833:
2378 case 1161:
2379 case 713: // xinef, bloodworms
2380 numSummons = (damage > 0) ? damage : 1;
2381 break;
2382 default:
2383 numSummons = 1;
2384 break;
2385 }
2386
2387 switch (properties->Category)
2388 {
2392 if (properties->Flags & 512)
2393 {
2394 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2395 break;
2396 }
2397 switch (properties->Type)
2398 {
2399 case SUMMON_TYPE_PET:
2402 case SUMMON_TYPE_MINION:
2403 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2404 break;
2405 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2408 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2409 break;
2411 case SUMMON_TYPE_TOTEM:
2412 {
2413 // protection code
2414 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2415 if (!summon || !summon->IsTotem())
2416 return;
2417
2418 // Mana Tide Totem
2419 if (m_spellInfo->Id == 16190)
2421
2422 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2423 {
2424 summon->SetMaxHealth(damage);
2425 summon->SetHealth(damage);
2426 }
2427 break;
2428 }
2430 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2434 ));
2435 [[fallthrough]];
2436 case SUMMON_TYPE_JEEVES:
2437 {
2438 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2439 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2440 return;
2441
2442 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2444
2445 summon->SetImmuneToAll(true);
2447
2448 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2449 //summon->AI()->EnterEvadeMode();
2450 if (properties->Type != SUMMON_TYPE_JEEVES)
2451 {
2453 summon->GetMotionMaster()->Clear(false);
2455 }
2456 break;
2457 }
2458 default:
2459 {
2460 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2461
2462 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2463
2464 for (uint32 count = 0; count < numSummons; ++count)
2465 {
2466 Position pos;
2467 if (count == 0)
2468 pos = *destTarget;
2469 else
2470 // randomize position for multiple summons
2471 pos = m_caster->GetRandomPoint(*destTarget, radius);
2472
2473 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2474 if (!summon)
2475 continue;
2476
2477 summon->SetTempSummonType(summonType);
2478
2479 if (properties->Category == SUMMON_CATEGORY_ALLY)
2480 {
2483 }
2484
2485 ExecuteLogEffectSummonObject(effIndex, summon);
2486 }
2487 return;
2488 }
2489 }//switch
2490 break;
2492 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2493 if (m_originalCaster)
2495 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2496 break;
2498 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2499 break;
2501 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2502 // to cast a ride vehicle spell on the summoned unit.
2503 //float x, y, z;
2504 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2505 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2506 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2508
2509 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2510 if (!summon || !summon->IsVehicle())
2511 return;
2512
2513 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2515 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2516 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2517 {
2518 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2519 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2520 spellId = spellInfo->Id;
2521 }
2522
2523 // xinef: if we have small value, it indicates seat position
2524 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2525 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2526 else
2527 m_originalCaster->CastSpell(summon, spellId, true);
2528
2529 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2530 //uint32 faction = properties->Faction;
2531 //if (!faction)
2532 uint32 faction = m_originalCaster->GetFaction();
2533
2534 summon->SetFaction(faction);
2535 break;
2536 }
2537
2538 if (summon)
2539 {
2541 ExecuteLogEffectSummonObject(effIndex, summon);
2542 }
2543}
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition DBCStructure.h:2024
@ MOTION_SLOT_ACTIVE
Definition MotionMaster.h:64
TempSummonType
Definition Object.h:47
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:54
constexpr float MINI_PET_SUMMON_ANGLE
Definition PetDefines.h:208
constexpr float MINI_PET_FOLLOW_ANGLE
Definition PetDefines.h:209
@ SUMMON_TYPE_VEHICLE2
Definition SharedDefines.h:3544
@ SUMMON_TYPE_LIGHTWELL
Definition SharedDefines.h:3545
@ SUMMON_TYPE_MINION
Definition SharedDefines.h:3537
@ SUMMON_TYPE_GUARDIAN
Definition SharedDefines.h:3536
@ SUMMON_TYPE_JEEVES
Definition SharedDefines.h:3546
@ SUMMON_TYPE_PET
Definition SharedDefines.h:3535
@ SUMMON_TYPE_TOTEM
Definition SharedDefines.h:3538
@ SUMMON_TYPE_VEHICLE
Definition SharedDefines.h:3543
@ SUMMON_TYPE_MINIPET
Definition SharedDefines.h:3539
@ SUMMON_TYPE_GUARDIAN2
Definition SharedDefines.h:3540
@ SUMMON_CATEGORY_VEHICLE
Definition SharedDefines.h:3527
@ SUMMON_CATEGORY_ALLY
Definition SharedDefines.h:3524
@ SUMMON_CATEGORY_WILD
Definition SharedDefines.h:3523
@ SUMMON_CATEGORY_UNK
Definition SharedDefines.h:3528
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ UNIT_MASK_MINION
Definition UnitDefines.h:157
NPCFlags
Non Player Character flags.
Definition UnitDefines.h:317
@ REACT_PASSIVE
Definition Unit.h:555
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition VehicleDefines.h:52
void SelectLevel(bool changelevel=true)
Definition Creature.cpp:1471
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition Object.cpp:2158
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true, bool inheritSpeed=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:446
void Clear(bool reset=true)
Definition MotionMaster.h:192
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:287
void SetFacingToObject(WorldObject *object, Milliseconds timed=0ms)
Definition Unit.cpp:20517
void SetFaction(uint32 faction)
Definition Unit.cpp:10241
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:10783
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:731
void SetMaxHealth(uint32 val)
Definition Unit.cpp:15772
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:706
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:756
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:11073
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:914
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2765
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1289
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1528
uint32 npcflag
Definition CreatureData.h:199
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition Spell.h:229
uint32 Flags
Definition DBCStructure.h:1915
uint32 Type
Definition DBCStructure.h:1913
uint32 Id
Definition DBCStructure.h:1910

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), WorldObject::GetDistance2d(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), WorldObject::GetNearPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, m_spellValue, MAX_VEHICLE_SEATS, MINI_PET_FOLLOW_ANGLE, MINI_PET_SUMMON_ANGLE, SpellValue::MiscVal, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Position::Relocate(), Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFacingToObject(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3089{
3091 return;
3092
3093 if (m_caster->GetPetGUID())
3094 return;
3095
3096 if (!unitTarget)
3097 return;
3098
3099 if (!unitTarget->IsCreature())
3100 return;
3101
3102 Creature* creatureTarget = unitTarget->ToCreature();
3103
3104 if (creatureTarget->IsPet())
3105 return;
3106
3108 return;
3109
3110 // cast finish successfully
3111 //SendChannelUpdate(0);
3112 finish();
3113
3114 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3115 if (!pet) // in very specific state like near world end/etc.
3116 return;
3117
3118 // "kill" original creature
3119 creatureTarget->DespawnOrUnsummon();
3120
3121 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3122
3123 // prepare visual effect for levelup
3124 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3125
3126 // add to world
3127 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3128
3129 // visual effect for levelup
3130 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3131
3132 // caster have pet now
3133 m_caster->SetMinion(pet, true);
3134
3135 pet->InitTalentForLevel();
3136
3137 if (m_caster->IsPlayer())
3138 {
3141 }
3142}
@ UNIT_FIELD_LEVEL
Definition UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3285{
3287 return;
3288
3289 if (!unitTarget)
3290 return;
3291
3292 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3293 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3294 {
3295 m_caster->CastSpell(unitTarget, 67485, true);
3297 }
3298
3299 // this effect use before aura Taunt apply for prevent taunt already attacking target
3300 // for spell as marked "non effective at already attacking target"
3302 {
3304 return;
3305 }
3306
3308 {
3309 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3310 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3312 if (topThreat > myThreat)
3313 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3314
3315 //Set aggro victim to caster
3317 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3318 }
3319}
@ SPELL_AURA_MOD_TAUNT
Definition SpellAuraDefines.h:74
Definition ThreatMgr.h:48
float GetThreat() const
Definition ThreatMgr.h:62
HostileReference * getMostHated() const
Definition ThreatMgr.h:172
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition ThreatMgr.cpp:261
bool empty() const
Definition ThreatMgr.h:167
void setCurrentVictim(HostileReference *hostileRef)
Definition ThreatMgr.cpp:640
void DoAddThreat(Unit *victim, float threat)
Definition ThreatMgr.cpp:521
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition ThreatMgr.cpp:593
ThreatContainer & GetOnlineContainer()
Definition ThreatMgr.h:279
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:14728

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1181{
1183 return;
1184
1185 if (!unitTarget || unitTarget->IsInFlight())
1186 return;
1187
1188 if (unitTarget->IsPlayer())
1189 {
1190 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1191 }
1192
1193 // Pre effects
1194 switch (m_spellInfo->Id)
1195 {
1196 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1197 if (Player* target = unitTarget->ToPlayer())
1198 {
1199 uint32 mapid = destTarget->GetMapId();
1200 float x, y, z, orientation;
1201 destTarget->GetPosition(x, y, z, orientation);
1202 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1203 }
1204 return;
1205 }
1206
1207 // If not exist data for dest location - return
1208 if (!m_targets.HasDst())
1209 {
1210 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1211 return;
1212 }
1213
1214 // Init dest coordinates
1215 uint32 mapid = destTarget->GetMapId();
1216 if (mapid == MAPID_INVALID)
1217 mapid = unitTarget->GetMapId();
1218 float x, y, z, orientation;
1219 destTarget->GetPosition(x, y, z, orientation);
1220 if (!orientation && m_targets.GetUnitTarget())
1221 orientation = m_targets.GetUnitTarget()->GetOrientation();
1222 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1223
1224 if (mapid == unitTarget->GetMapId())
1225 {
1226 if (unitTarget->GetVehicleKit()) // we are vehicle!
1227 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1228 else
1229 {
1231 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1232 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1234 }
1235 }
1236 else if (unitTarget->IsPlayer())
1237 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1238 else
1239 {
1240 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1241 return;
1242 }
1243
1244 // post effects for TARGET_DEST_DB
1245 switch (m_spellInfo->Id)
1246 {
1247 // Dimensional Ripper - Everlook
1248 case 23442:
1249 {
1250 int32 r = irand(0, 119);
1251 if (r >= 70) // 7/12 success
1252 {
1253 if (r < 100) // 4/12 evil twin
1254 m_caster->CastSpell(m_caster, 23445, true);
1255 else // 1/12 fire
1256 m_caster->CastSpell(m_caster, 23449, true);
1257 }
1258 return;
1259 }
1260 // Ultrasafe Transporter: Toshley's Station
1261 case 36941:
1262 {
1263 if (roll_chance_i(50)) // 50% success
1264 {
1265 int32 rand_eff = urand(1, 7);
1266 switch (rand_eff)
1267 {
1268 case 1:
1269 // soul split - evil
1270 m_caster->CastSpell(m_caster, 36900, true);
1271 break;
1272 case 2:
1273 // soul split - good
1274 m_caster->CastSpell(m_caster, 36901, true);
1275 break;
1276 case 3:
1277 // Increase the size
1278 m_caster->CastSpell(m_caster, 36895, true);
1279 break;
1280 case 4:
1281 // Decrease the size
1282 m_caster->CastSpell(m_caster, 36893, true);
1283 break;
1284 case 5:
1285 // Transform
1286 {
1288 m_caster->CastSpell(m_caster, 36897, true);
1289 else
1290 m_caster->CastSpell(m_caster, 36899, true);
1291 break;
1292 }
1293 case 6:
1294 // chicken
1295 m_caster->CastSpell(m_caster, 36940, true);
1296 break;
1297 case 7:
1298 // evil twin
1299 m_caster->CastSpell(m_caster, 23445, true);
1300 break;
1301 }
1302 }
1303 return;
1304 }
1305 }
1306}
@ TELE_TO_SPELL
Definition Player.h:819
@ TELE_TO_GM_MODE
Definition Player.h:815
#define MAPID_INVALID
Definition Position.h:253
TeamId GetTeamId(bool original=false) const
Definition Player.h:2125
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition Player.cpp:1353
Vehicle * GetVehicleKit() const
Definition Unit.h:1904
void TeleportVehicle(float x, float y, float z, float ang)
Definition Vehicle.cpp:571

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3659{
3661 return;
3662
3663 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3664 return;
3665
3666 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3668 return;
3669
3671}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition Unit.cpp:14767

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5904{
5906 return;
5907
5908 if (m_caster->IsPlayer())
5909 {
5910 if (Aura* aur = m_caster->GetAura(49152))
5911 aur->RecalculateAmountOfEffects();
5912 else
5913 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5914
5916 }
5917}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13164

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2826{
2828 return;
2829
2830 if (!m_caster->IsPlayer())
2831 return;
2832 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2833 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2834 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2835}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5374{
5376 return;
5377
5378 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5379
5380 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5381
5382 if (!goinfo)
5383 {
5384 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5385 return;
5386 }
5387
5388 float fx, fy, fz;
5389
5390 if (m_targets.HasDst())
5391 destTarget->GetPosition(fx, fy, fz);
5392 //FIXME: this can be better check for most objects but still hack
5393 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5394 {
5395 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5397 }
5398 else
5399 {
5400 //GO is always friendly to it's creator, get range for friends
5401 float min_dis = m_spellInfo->GetMinRange(true);
5402 float max_dis = m_spellInfo->GetMaxRange(true);
5403 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5404
5406 }
5407
5408 // Seaforium charge
5409 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5410 {
5411 fx = m_caster->GetPositionX();
5412 fy = m_caster->GetPositionY();
5413 fz = m_caster->GetPositionZ();
5414 }
5415
5416 Map* cMap = m_caster->GetMap();
5417
5418 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5419
5420 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5421 {
5422 delete pGameObj;
5423 return;
5424 }
5425
5426 int32 duration = m_spellInfo->GetDuration();
5427
5428 switch (goinfo->type)
5429 {
5431 {
5433 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5434
5435 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5436 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5437 int32 lastSec = 0;
5438 switch (urand(0, 2))
5439 {
5440 case 0:
5441 lastSec = 3;
5442 break;
5443 case 1:
5444 lastSec = 7;
5445 break;
5446 case 2:
5447 lastSec = 13;
5448 break;
5449 }
5450
5451 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5452 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5453
5454 break;
5455 }
5457 {
5458 if (m_caster->IsPlayer())
5459 {
5460 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5461 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5462 }
5463 break;
5464 }
5465 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5466 m_caster->AddGameObject(pGameObj);
5467 break;
5470 default:
5471 break;
5472 }
5473
5474 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5475
5476 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5477
5478 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5479 pGameObj->SetSpellId(m_spellInfo->Id);
5480
5481 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5482
5483 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5484 //m_caster->AddGameObject(pGameObj);
5485 //m_ObjToDel.push_back(pGameObj);
5486
5487 cMap->AddToMap(pGameObj, true);
5488
5489 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5490 {
5491 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5492 linkedTrap->SetSpellId(m_spellInfo->Id);
5493 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5494
5495 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5496 }
5497
5498 if (Player* player = m_caster->ToPlayer())
5499 {
5500 player->SetCanTeleport(true);
5501 }
5502}
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:117
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition SharedDefines.h:1587
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1596
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1588
@ UNIT_FIELD_CHANNEL_OBJECT
Definition UpdateFields.h:93
void SetOwnerGUID(ObjectGuid owner)
Definition GameObject.h:163
void AddUniqueUse(Player *player)
Definition GameObject.cpp:910
float GetMinRange(bool positive=false) const
Definition SpellInfo.cpp:2208

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GameObject, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
943{
946 return;
947
948 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
949
950 // normal case
951 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
952 if (!spellInfo)
953 {
954 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
955 return;
956 }
957
958 SpellCastTargets targets;
960 {
961 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
962 return;
963 targets.SetUnitTarget(unitTarget);
964 }
965 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
966 {
967 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
968 return;
969
971 targets.SetDst(m_targets);
972
973 targets.SetUnitTarget(m_caster);
974 }
975
976 CustomSpellValues values;
977 // set basepoints for trigger with value effect
979 {
980 // maybe need to set value only when basepoints == 0?
984 }
985
986 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
987 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
988 {
989 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
990 }
991
992 // original caster guid only for GO cast
993 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
994}
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition SharedDefines.h:937
@ TARGET_FLAG_DEST_LOCATION
Definition SpellInfo.h:52
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition SpellInfo.cpp:1038
uint32 CategoryRecoveryTime
Definition SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1051{
1053 return;
1054
1055 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1056 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1057
1058 if (!spellInfo)
1059 {
1060 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1061 return;
1062 }
1063
1064 finish();
1065
1066 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1067}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
786{
789 return;
790
791 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
792
794 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
796 {
797 // special cases
798 switch (triggered_spell_id)
799 {
800 // Mirror Image
801 case 58832:
802 {
803 // Glyph of Mirror Image
804 if (m_caster->HasAura(63093))
805 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
806
807 break;
808 }
809 // Demonic Empowerment -- succubus
810 case 54437:
811 {
815
816 // Cast Lesser Invisibility
817 unitTarget->CastSpell(unitTarget, 7870, true);
818 return;
819 }
820 // just skip
821 case 23770: // Sayge's Dark Fortune of *
822 // not exist, common cooldown can be implemented in scripts if need.
823 return;
824 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
825 case 29284:
826 {
827 // Brittle Armor
828 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
829 if (!spell)
830 return;
831
832 for (uint32 j = 0; j < spell->StackAmount; ++j)
833 m_caster->CastSpell(unitTarget, spell->Id, true);
834 return;
835 }
836 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
837 case 29286:
838 {
839 // Mercurial Shield
840 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
841 if (!spell)
842 return;
843
844 for (uint32 j = 0; j < spell->StackAmount; ++j)
845 m_caster->CastSpell(unitTarget, spell->Id, true);
846 return;
847 }
848 // Cloak of Shadows
849 case 35729:
850 {
853 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
854 {
855 // remove all harmful spells on you...
856 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
857
858 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
859 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
860 return;
861
862 bool dmgClassNone = false;
864 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
865 {
866 if ((iter->second->GetEffectMask() & (1 << i)) &&
867 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
868 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
869 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
870 {
871 dmgClassNone = false;
872 break;
873 }
874 dmgClassNone = true;
875 }
876
877 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
878 // ignore positive and passive auras
879 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
880 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
882 {
883 m_caster->RemoveAura(iter);
884 }
885 else
886 ++iter;
887 }
888 return;
889 }
890 }
891 }
892
893 // normal case
894 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
895 if (!spellInfo)
896 {
897 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
898 return;
899 }
900
901 SpellCastTargets targets;
903 {
904 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
905 return;
906 targets.SetUnitTarget(unitTarget);
907 }
908 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
909 {
910 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
911 return;
912
914 targets.SetDst(m_targets);
915
916 if (Unit* target = m_targets.GetUnitTarget())
917 targets.SetUnitTarget(target);
918 else
919 targets.SetUnitTarget(m_caster);
920 }
921
922 CustomSpellValues values;
923 // set basepoints for trigger with value effect
925 {
926 // maybe need to set value only when basepoints == 0?
930 }
931
932 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
933 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
934 {
935 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
936 }
937
938 // original caster guid only for GO cast
940}
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition SharedDefines.h:931
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:853
@ MECHANIC_BLEED
Definition SharedDefines.h:1351
@ DISPEL_ALL
Definition SharedDefines.h:1390
@ SPELL_AURA_MOD_STALKED
Definition SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition SpellAuraDefines.h:86

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1331{
1333 return;
1334
1335 if (!unitTarget)
1336 return;
1337
1338 Player* player = unitTarget->ToPlayer();
1339 if (!player)
1340 {
1341 return;
1342 }
1343
1344 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1345
1346 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1347 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1348 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1349}
#define SPEC_MASK_ALL
Definition Player.h:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition Player.cpp:3330

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2750{
2752 return;
2753
2754 if (!unitTarget || m_caster->IsPlayer())
2755 return;
2756
2757 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2759}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:8919

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
244{
245 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
246}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3322{
3324 return;
3325
3326 if (!unitTarget || !unitTarget->IsAlive())
3327 return;
3328
3329 // multiple weapon dmg effect workaround
3330 // execute only the last weapon damage
3331 // and handle all effects at once
3332 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3333 {
3334 switch (m_spellInfo->Effects[j].Effect)
3335 {
3340 return; // we must calculate only at last weapon effect
3341 break;
3342 }
3343 }
3344
3345 // some spell specific modifiers
3346 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3347 int32 spell_bonus = 0; // bonus specific for spell
3348 bool normalized = false;
3349
3351 {
3353 {
3354 switch (m_spellInfo->Id)
3355 {
3356 // Trial of the Champion, Black Knight, Obliterate
3357 case 67725:
3358 case 67883:
3359 {
3360 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3361 break;
3362 }
3363 }
3364 break;
3365 }
3367 {
3368 // Devastate (player ones)
3369 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3370 {
3371 m_caster->CastSpell(unitTarget, 58567, true);
3372
3373 if (Aura* aur = unitTarget->GetAura(58567))
3374 {
3375 // 58388 - Glyph of Devastate dummy aura.
3376 if (m_caster->HasAura(58388))
3377 aur->ModStackAmount(1);
3378
3379 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3380 }
3381 }
3382 break;
3383 }
3384 case SPELLFAMILY_ROGUE:
3385 {
3386 // Fan of Knives, Hemorrhage, Ghostly Strike
3387 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3388 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3389 {
3390 // Hemorrhage
3391 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3392 {
3394 }
3395 // 50% more damage with daggers
3396 if (m_caster->IsPlayer())
3397 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3398 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3399 AddPct(totalDamagePercentMod, 50.0f);
3400 }
3401 // Mutilate (for each hand)
3402 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3403 {
3404 bool found = false;
3405 // fast check
3407 found = true;
3408 // full aura scan
3409 else
3410 {
3412 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3413 {
3414 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3415 {
3416 found = true;
3417 break;
3418 }
3419 }
3420 }
3421
3422 if (found)
3423 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3424 }
3425 break;
3426 }
3428 {
3429 switch (m_spellInfo->Id)
3430 {
3431 case 20467: // Seal of Command Unleashed
3432 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3434 break;
3435 case 53385: // Divine Storm deals normalized damage
3436 normalized = true;
3437 break;
3438 default:
3439 break;
3440 }
3441 break;
3442 }
3443 case SPELLFAMILY_SHAMAN:
3444 {
3445 // Skyshatter Harness item set bonus
3446 // Stormstrike
3447 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3448 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3449 // Lava lash damage increased by Flametongue weapon
3451 AddPct(totalDamagePercentMod, 25.0f);
3452 break;
3453 }
3454 case SPELLFAMILY_DRUID:
3455 {
3456 // Mangle (Cat): CP
3457 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3458 {
3460 }
3461 // Shred, Maul - Rend and Tear
3463 {
3464 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3465 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3466 }
3467 break;
3468 }
3469 case SPELLFAMILY_HUNTER:
3470 {
3471 // Kill Shot
3472 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3473 {
3474 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3475 }
3476 break;
3477 }
3479 {
3480 // Plague Strike
3481 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3482 {
3483 // Glyph of Plague Strike
3484 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3485 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3486 break;
3487 }
3488 // Blood Strike
3489 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3490 {
3491 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3492 //Death Knight T8 Melee 4P Bonus
3493 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3494 AddPct(disease_amt, aurEff->GetAmount());
3495
3496 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3497
3498 // Glyph of Blood Strike
3499 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3501 AddPct(totalDamagePercentMod, 20.0f);
3502 break;
3503 }
3504 // Death Strike
3505 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3506 {
3507 // Glyph of Death Strike
3508 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3509 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3510 AddPct(totalDamagePercentMod, runic);
3511 break;
3512 }
3513 // Obliterate (12.5% more damage per disease)
3514 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3515 {
3516 bool consumeDiseases = true;
3517 // Annihilation
3519 // Do not consume diseases if roll sucesses
3520 if (roll_chance_i(aurEff->GetAmount()))
3521 consumeDiseases = false;
3522
3523 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3524 //Death Knight T8 Melee 4P Bonus
3525 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3526 AddPct(disease_amt, aurEff->GetAmount());
3527
3528 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3529 break;
3530 }
3531 // Blood-Caked Strike - Blood-Caked Blade
3532 if (m_spellInfo->SpellIconID == 1736)
3533 {
3534 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
3535 break;
3536 }
3537 // Heart Strike
3538 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3539 {
3540 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3541 //Death Knight T8 Melee 4P Bonus
3542 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3543 AddPct(disease_amt, aurEff->GetAmount());
3544
3545 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3546 break;
3547 }
3548 // Rune Strike
3549 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3550 {
3551 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3552 }
3553
3554 break;
3555 }
3556 }
3557
3558 float weaponDamagePercentMod = 100.0f;
3559 int32 fixed_bonus = 0;
3560
3561 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3562 {
3563 switch (m_spellInfo->Effects[j].Effect)
3564 {
3567 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3568 break;
3570 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3571 normalized = true;
3572 break;
3574 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3575 break;
3576 default:
3577 break; // not weapon damage effect, just skip
3578 }
3579 }
3580
3581 bool const isPhysical = (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL);
3582 if (isPhysical && (fixed_bonus || spell_bonus))
3583 {
3584 UnitMods unitMod;
3585 switch (m_attackType)
3586 {
3587 default:
3588 case BASE_ATTACK:
3589 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3590 break;
3591 case OFF_ATTACK:
3592 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3593 break;
3594 case RANGED_ATTACK:
3595 unitMod = UNIT_MOD_DAMAGE_RANGED;
3596 break;
3597 }
3598 float weapon_total_pct = m_caster->GetPctModifierValue(unitMod, TOTAL_PCT);
3599 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3600 spell_bonus = int32(spell_bonus * weapon_total_pct);
3601 }
3602
3603 int32 weaponDamage = 0;
3604 // Dancing Rune Weapon
3605 if (m_caster->GetEntry() == 27893)
3606 {
3607 if (Unit* owner = m_caster->GetOwner())
3608 weaponDamage = owner->CalculateDamage(m_attackType, normalized, isPhysical);
3609 }
3610 else
3611 {
3612 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, isPhysical);
3613 }
3614
3615 // Sequence is important
3616 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3617 {
3618 // We assume that a spell have at most one fixed_bonus
3619 // and at most one weaponDamagePercentMod
3620 switch (m_spellInfo->Effects[j].Effect)
3621 {
3625 weaponDamage += fixed_bonus;
3626 break;
3628 ApplyPct(weaponDamage, weaponDamagePercentMod);
3629 default:
3630 break; // not weapon damage effect, just skip
3631 }
3632 }
3633
3634 weaponDamage += spell_bonus;
3635 ApplyPct(weaponDamage, totalDamagePercentMod);
3636
3637 // prevent negative damage
3638 uint32 eff_damage(std::max(weaponDamage, 0));
3639
3640 // Add melee damage bonuses (also check for negative)
3643
3644 // Meteor like spells (divided damage to targets)
3646 {
3647 uint32 count = 0;
3648 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3649 if (ihit->effectMask & (1 << effIndex))
3650 ++count;
3651
3652 eff_damage /= count; // divide to all targets
3653 }
3654
3655 m_damage += eff_damage;
3656}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition ItemTemplate.h:359
@ POWER_RUNIC_POWER
Definition SharedDefines.h:286
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:910
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:820
@ AURA_STATE_DEADLY_POISON
Definition SharedDefines.h:1319
@ AURA_STATE_BLEEDING
Definition SharedDefines.h:1321
@ DISPEL_POISON
Definition SharedDefines.h:1387
UnitMods
Definition Unit.h:149
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:173
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:174
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:172
@ TOTAL_PCT
Definition Unit.h:136
float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
Definition Unit.cpp:15401
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13439
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition Unit.cpp:5970
bool HasDecreaseSpeedAura() const
Definition Unit.h:1806
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition Unit.cpp:5676
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition Unit.cpp:3018
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition Unit.cpp:12145
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13249

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), Unit::GetPctModifierValue(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasDecreaseSpeedAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_DUMMY, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5094{
5095 InitEffectExecuteData(effIndex);
5096 *m_effectExecuteData[effIndex] << uint32(entry);
5097}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8476

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5100{
5101 InitEffectExecuteData(effIndex);
5102 *m_effectExecuteData[effIndex] << uint32(entry);
5103}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5080{
5081 InitEffectExecuteData(effIndex);
5082 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5083 *m_effectExecuteData[effIndex] << int32(itemId);
5084 *m_effectExecuteData[effIndex] << int32(slot);
5085}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5066{
5067 InitEffectExecuteData(effIndex);
5068 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5069 *m_effectExecuteData[effIndex] << uint32(attCount);
5070}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5073{
5074 InitEffectExecuteData(effIndex);
5075 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5076 *m_effectExecuteData[effIndex] << uint32(spellId);
5077}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5088{
5089 InitEffectExecuteData(effIndex);
5090 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5091}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5118{
5119 InitEffectExecuteData(effIndex);
5120 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5121}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5057{
5058 InitEffectExecuteData(effIndex);
5059 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5060 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5061 *m_effectExecuteData[effIndex] << uint32(PowerType);
5062 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5063}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5112{
5113 InitEffectExecuteData(effIndex);
5114 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5115}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4427{
4428 if (!m_caster)
4429 return;
4430
4432 return;
4434
4435 if (m_spellInfo->IsChanneled())
4437
4440
4441 // Unsummon summon as possessed creatures on spell cancel
4443 {
4444 if (Unit* charm = m_caster->GetCharm())
4445 if (charm->IsCreature()
4446 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4447 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4448 ((Puppet*)charm)->UnSummon();
4449 }
4450
4451 if (Creature* creatureCaster = m_caster->ToCreature())
4452 creatureCaster->ReleaseFocus(this);
4453
4454 if (ok)
4455 {
4458 }
4459 else
4460 {
4461 if (m_caster->IsPlayer())
4462 {
4463 // Xinef: Restore spell mods in case of fail cast
4465
4466 // Xinef: Reset cooldown event in case of fail cast
4469
4470 // Rogue fix: Remove Cold Blood if Mutilate off-hand failed
4471 if (m_spellInfo->Id == 27576) // Mutilate, off-hand
4472 if (m_caster->HasAura(14177))
4473 m_caster->RemoveAura(14177);
4474 }
4475 return;
4476 }
4477
4478 // pussywizard:
4481
4483 {
4484 // Unsummon statue
4486 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4487 if (spellInfo && spellInfo->SpellIconID == 2056)
4488 {
4489 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4491 return;
4492 }
4493 }
4494
4495 // potions disabled by client, send event "not in combat" if need
4498
4499 // Take mods after trigger spell (needed for 14177 to affect 48664)
4500 // mods are taken only on succesfull cast and independantly from targets of the spell
4501 if (Player* player = m_caster->GetSpellModOwner())
4502 player->RemoveSpellMods(this);
4503
4504 // xinef: clear reactive auras states after spell cast
4507
4508 // Stop Attack for some spells
4511}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:159
@ AURA_STATE_DEFENSE
Definition SharedDefines.h:1303
@ AURA_STATE_HUNTER_PARRY
Definition SharedDefines.h:1309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:207
@ UNIT_MASK_PUPPET
Definition UnitDefines.h:162
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition Map.cpp:2514
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1549
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:14667
void UpdateInterruptMask()
Definition Unit.cpp:768
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:10707

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), JustDied, LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Unit::RemoveAura(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8472{
8474}
void SendLogExecute()
Definition Spell.cpp:5022

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

◆ GetCastTimeRemaining()

int32 Spell::GetCastTimeRemaining ( )
inline
562{ return m_timer;}

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8935{
8936 std::stringstream sstr;
8937 sstr << std::boolalpha
8938 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8939 << " State: " << getState();
8940 return sstr.str();
8941}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
574{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
577{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
588{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2036{
2037 // this function selects which containers need to be searched for spell target
2039
2040 // filter searchers based on searched object type
2041 switch (objType)
2042 {
2049 break;
2053 break;
2054 default:
2055 break;
2056 }
2058 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2062 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2064 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2065
2066 if (condList)
2067 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2068 return retMask;
2069}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:75
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:72
@ GRID_MAP_TYPE_MASK_ALL
Definition GridDefines.h:76
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition GridDefines.h:74
@ GRID_MAP_TYPE_MASK_CORPSE
Definition GridDefines.h:71
@ SPELL_ATTR5_NOT_ON_PLAYER
Definition SharedDefines.h:585
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition SharedDefines.h:467
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition SharedDefines.h:516
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition SharedDefines.h:512
@ TARGET_OBJECT_TYPE_CORPSE
Definition SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition SpellInfo.h:104

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR5_NOT_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
595{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
603{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4115{
4116 if (!UpdatePointers())
4117 {
4118 // finish the spell if UpdatePointers() returned false, something wrong happened there
4119 finish(false);
4120 return 0;
4121 }
4122
4123 Player* modOwner = m_caster->GetSpellModOwner();
4124 if (modOwner)
4125 modOwner->SetSpellModTakingSpell(this, true);
4126
4127 uint64 next_time = m_delayTrajectory;
4128
4130
4131 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4132 {
4134 m_immediateHandled = true;
4136 next_time = 0;
4137 }
4138
4139 bool single_missile = (m_targets.HasDst());
4140
4141 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4142 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4143 {
4144 if (ihit->processed == false)
4145 {
4146 if (single_missile || ihit->timeDelay <= t_offset)
4147 {
4148 ihit->timeDelay = t_offset;
4149 DoAllEffectOnTarget(&(*ihit));
4150 }
4151 else if (next_time == 0 || ihit->timeDelay < next_time)
4152 next_time = ihit->timeDelay;
4153 }
4154 }
4155
4156 // now recheck gameobject targeting correctness
4157 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4158 {
4159 if (ighit->processed == false)
4160 {
4161 if (single_missile || ighit->timeDelay <= t_offset)
4162 DoAllEffectOnTarget(&(*ighit));
4163 else if (next_time == 0 || ighit->timeDelay < next_time)
4164 next_time = ighit->timeDelay;
4165 }
4166 }
4167
4169
4170 if (modOwner)
4171 modOwner->SetSpellModTakingSpell(this, false);
4172
4173 // All targets passed - need finish phase
4174 if (next_time == 0)
4175 {
4176 // spell is finished, perform some last features of the spell here
4178
4179 finish(true); // successfully finish spell cast
4180
4181 // return zero, spell is finished now
4182 return 0;
4183 }
4184 else
4185 {
4186 // spell is unfinished, return next execution time
4187 return next_time;
4188 }
4189}
void _handle_finish_phase()
Definition Spell.cpp:4219
void PrepareTargetProcessing()
Definition Spell.cpp:8466
void _handle_immediate_phase()
Definition Spell.cpp:4191
void FinishTargetProcessing()
Definition Spell.cpp:8471

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4055{
4056 // start channeling if applicable
4057 if (m_spellInfo->IsChanneled())
4058 {
4059 int32 duration = m_spellInfo->GetDuration();
4061 duration = -1;
4062
4063 if (duration > 0)
4064 {
4065 // First mod_duration then haste - see Missile Barrage
4066 // Apply duration mod
4067 if (Player* modOwner = m_caster->GetSpellModOwner())
4068 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4069
4070 // Apply haste mods
4072 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4073
4076 m_channeledDuration = duration;
4077 SendChannelStart(duration);
4078 }
4079 else if (duration == -1)
4080 {
4083 SendChannelStart(duration);
4084 }
4085 }
4086
4088
4089 // process immediate effects (items, ground, etc.) also initialize some variables
4091
4092 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4093 DoAllEffectOnTarget(&(*ihit));
4094
4095 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4096 DoAllEffectOnTarget(&(*ihit));
4097
4099
4100 // spell is finished, perform some last features of the spell here
4102
4103 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4104 TakeCastItem();
4105
4106 // handle ammo consumption for Hunter's volley spell
4108 TakeAmmo();
4109
4111 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4112}
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5155
void TakeAmmo()
Definition Spell.cpp:5328
void AddInterruptMask(uint32 mask)
Definition Unit.h:1589

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5578{
5580 return;
5581
5582 effectHandleMode = mode;
5583 unitTarget = pUnitTarget;
5584 itemTarget = pItemTarget;
5585 gameObjTarget = pGOTarget;
5587
5588 uint8 eff = m_spellInfo->Effects[i].Effect;
5589
5590 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5591
5592 // we do not need DamageMultiplier here.
5593 damage = CalculateSpellDamage(i, nullptr);
5594
5595 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5596
5597 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5598 {
5599 (this->*SpellEffects[eff])((SpellEffIndex)i);
5600 }
5601}
SpellEffIndex
Definition SharedDefines.h:30
SpellEffects
Definition SharedDefines.h:789
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:954
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition Spell.cpp:8585
WorldLocation _position
Definition Spell.h:113

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8225{
8226 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8227 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8228 {
8229 // don't do anything for empty effect
8230 if (!m_spellInfo->Effects[i].IsEffect())
8231 continue;
8232
8233 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8234 }
8235
8236 float multiplier[MAX_SPELL_EFFECTS];
8237 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8238 if (m_applyMultiplierMask & (1 << i))
8239 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8240
8243 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8244 {
8245 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8246 usesAmmo = false;
8247 }
8248
8250
8251 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8252 {
8253 TargetInfo& target = *ihit;
8254
8255 uint32 mask = target.effectMask;
8256 if (!mask)
8257 continue;
8258
8259 // do not consume ammo anymore for Hunter's volley spell
8261 usesAmmo = false;
8262
8263 if (usesAmmo)
8264 {
8265 bool ammoTaken = false;
8266 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8267 {
8268 if (!(mask & 1 << i))
8269 continue;
8270 switch (m_spellInfo->Effects[i].Effect)
8271 {
8277 ammoTaken = true;
8278 TakeAmmo();
8279 }
8280 if (ammoTaken)
8281 break;
8282 }
8283 }
8284
8285 DoAllEffectOnLaunchTarget(target, multiplier);
8286 }
8287
8289}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:791
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:184
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition Spell.cpp:8291

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5531{
5532 if (m_UniqueTargetInfo.empty())
5533 return;
5534
5536 return;
5537
5538 float threat = 0.0f;
5539 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5540 {
5541 if (threatEntry->apPctMod != 0.0f)
5542 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5543
5544 threat += threatEntry->flatMod;
5545 }
5547 threat += m_spellInfo->SpellLevel;
5548
5549 // past this point only multiplicative effects occur
5550 if (threat == 0.0f)
5551 return;
5552
5553 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5554 threat /= m_UniqueTargetInfo.size();
5555
5556 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5557 {
5558 float threatToAdd = threat;
5559 if (ihit->missCondition != SPELL_MISS_NONE)
5560 threatToAdd = 0.0f;
5561
5562 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5563 if (!target)
5564 continue;
5565
5566 bool IsFriendly = m_caster->IsFriendlyTo(target);
5567 // positive spells distribute threat among all units that are in combat with target, like healing
5569 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5570 // for negative spells threat gets distributed among affected targets
5571 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5572 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5573 }
5574 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5575}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition boss_chess_event.cpp:180
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:2727
Definition SpellMgr.h:378

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8095{
8096 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8097 if (itr->effectMask & (1 << effect))
8098 return true;
8099
8100 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8101 if (itr->effectMask & (1 << effect))
8102 return true;
8103
8104 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8105 if (itr->effectMask & (1 << effect))
8106 return true;
8107
8108 return false;
8109}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8477{
8478 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8479 if (!m_effectExecuteData[effIndex])
8480 {
8481 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8482 // first dword - target counter
8483 *m_effectExecuteData[effIndex] << uint32(1);
8484 }
8485 else
8486 {
8487 // increase target counter by one
8488 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8489 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8490 }
8491}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
719{
720 m_targets = targets;
721 // this function tries to correct spell explicit targets for spell
722 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
723 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
724 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
725
726 if (WorldObject* target = m_targets.GetObjectTarget())
727 {
728 // check if object target is valid with needed target flags
729 // for unit case allow corpse target mask because player with not released corpse is a unit target
730 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
731 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
732 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
734 }
735 else
736 {
737 // try to select correct unit target if not provided by client or by serverside cast
738 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
739 {
740 Unit* unit = nullptr;
741 // try to use player selection as a target
742 if (Player* playerCaster = m_caster->ToPlayer())
743 {
744 // selection has to be found and to be valid target for the spell
745 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
747 unit = selectedUnit;
748 }
749 // try to use attacked unit as a target
750 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
751 unit = m_caster->GetVictim();
752
753 // didn't find anything - let's use self as target
754 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
755 unit = m_caster;
756
758 }
759 }
760
761 // check if spell needs dst target
762 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
763 {
764 // and target isn't set
765 if (!m_targets.HasDst())
766 {
767 // try to use unit target if provided
768 if (WorldObject* target = targets.GetObjectTarget())
769 m_targets.SetDst(*target);
770 // or use self if not available
771 else
773 }
774 }
775 else
777
778 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
779 {
780 if (!targets.HasSrc())
782 }
783 else
785}
@ TARGET_FLAG_UNIT_RAID
Definition SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition SpellInfo.h:49
void RemoveDst()
Definition Spell.cpp:447
void RemoveSrc()
Definition Spell.cpp:390

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8069{
8072 {
8073 return false;
8074 }
8075
8077 {
8078 return false;
8079 }
8080
8081 return true;
8082}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition SharedDefines.h:640

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
641 {
642 if (m_delayAtDamageCount >= 2)
643 return true;
644
646 return false;
647 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
572{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8217{
8218 if (target->IsAlive())
8220
8222}
bool IsRequiringDeadTarget() const
Definition SpellInfo.cpp:1222
bool IsAllowingDeadTarget() const
Definition SpellInfo.cpp:1227

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8500{
8501 if (_scriptsLoaded)
8502 return;
8503 _scriptsLoaded = true;
8504 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8505 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8506 {
8507 if (!(*itr)->_Load(this))
8508 {
8509 std::list<SpellScript*>::iterator bitr = itr;
8510 ++itr;
8511 delete (*bitr);
8512 m_loadedScripts.erase(bitr);
8513 continue;
8514 }
8515 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8516 (*itr)->Register();
8517 ++itr;
8518 }
8519}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8905{
8906 if (!m_caster || !m_caster->IsInWorld())
8907 return;
8908
8909 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8910
8911 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8912 // can succeed with a lockId of 0
8913 if (m_spellInfo->Id == 21651)
8914 {
8915 if (GameObject* go = m_targets.GetGOTarget())
8916 {
8917 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8918 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8919 {
8920 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8921 visual->prepare(&m_targets);
8922 }
8923 }
8924 }
8925}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2619
@ TRIGGERED_NONE
Definition SpellDefines.h:133

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3404{
3405 if (m_CastItem)
3406 {
3408 }
3409 else
3410 {
3412 }
3413
3414 InitExplicitTargets(*targets);
3415
3416 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3417 {
3418 finish(false);
3419 return SPELL_FAILED_UNKNOWN;
3420 }
3421
3422 // Fill aura scaling information
3424 {
3425 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3426 {
3427 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3430 {
3431 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3433 {
3434 m_auraScaleMask |= (1 << i);
3435 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3436 {
3437 m_auraScaleMask = 0;
3438 break;
3439 }
3440 }
3441 }
3442 }
3443 }
3444
3446
3447 if (triggeredByAura)
3448 {
3449 m_triggeredByAuraSpell.Init(triggeredByAura);
3450 }
3451
3452 // create and add update event for this spell
3453 _spellEvent = new SpellEvent(this);
3455
3456 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3457 {
3459 finish(false);
3461 }
3462
3463 //Prevent casting at cast another spell (ServerSide check)
3465 {
3467 finish(false);
3469 }
3470
3471 LoadScripts();
3472
3473 OnSpellLaunch();
3474
3476
3477 // Set combo point requirement
3479 m_needComboPoints = false;
3480
3481 SpellCastResult result = CheckCast(true);
3482 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3483 {
3484 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3485 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3486 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3487 // a possible alternative sollution for those would be validating aura target on unit state change
3488 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3489 {
3491 triggeredByAura->GetBase()->SetDuration(0);
3492 }
3493
3494 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3496 {
3497 SendCastResult(result);
3498
3499 finish(false);
3500 return result;
3501 }
3502 }
3503
3504 // Prepare data for triggers
3505 prepareDataForTriggerSystem(triggeredByAura);
3506
3507 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3509
3510 if (m_caster->IsPlayer())
3512 m_casttime = 0;
3513
3514 // don't allow channeled spells / spells with cast time to be casted while moving
3515 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3517 {
3518 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3520 {
3522 finish(false);
3523 return SPELL_FAILED_MOVING;
3524 }
3525 }
3526
3527 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3528 if (m_CastItem)
3529 {
3530 bool selectTargets = false;
3531 bool nearbyDest = false;
3532
3533 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3534 {
3535 if (!m_spellInfo->Effects[i].IsEffect())
3536 continue;
3537
3538 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3539 {
3540 selectTargets = false;
3541 break;
3542 }
3543
3544 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3545 {
3546 nearbyDest = true;
3547 }
3548
3549 // xinef: by default set it to false, and to true if any valid target is found
3550 selectTargets = true;
3551 }
3552
3553 if (selectTargets)
3554 {
3556 _spellTargetsSelected = true;
3557 bool spellFailed = false;
3558
3559 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3560 {
3561 // no valid nearby target unit or game object found; check if nearby destination type
3562 if (nearbyDest)
3563 {
3564 if (!m_targets.HasDst())
3565 {
3566 // no valid target destination
3567 spellFailed = true;
3568 }
3569 }
3570 else
3571 {
3572 spellFailed = true;
3573 }
3574 }
3575
3576 if (spellFailed)
3577 {
3579 finish(false);
3581 }
3582 }
3583 }
3584
3585 // set timer base at cast time
3586 ReSetTimer();
3587
3588 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3589
3590 // prevent exploit that allows to cast spell while sitting
3593
3594 //Containers for channeled spells have to be set
3595 //TODO:Apply this to all casted spells if needed
3596 // Why check duration? 29350: channelled triggers channelled
3598 cast(true);
3599 else
3600 {
3601 // stealth must be removed at cast starting (at show channel bar)
3602 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3604 {
3605 // Farsight spells exception
3606 uint32 exceptSpellId = 0;
3608 {
3609 exceptSpellId = m_spellInfo->Id;
3610 }
3611
3614 }
3615
3618
3619 // set target for proper facing
3621 {
3624 {
3625 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3626 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3628 }
3629 }
3630
3631 //item: first cast may destroy item and second cast causes crash
3632 // xinef: removed !m_spellInfo->StartRecoveryTime
3633 // second los check failed in events
3634 // xinef: removed itemguid check, currently there is no such item in database
3636 cast(true);
3637
3640 }
3641
3642 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3643
3644 return SPELL_CAST_OK;
3645}
@ CHEAT_CASTTIME
Definition Player.h:997
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:824
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:854
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition SharedDefines.h:420
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition SpellDefines.h:138
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition SpellDefines.h:142
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition SpellDefines.h:140
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition SpellDefines.h:26
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:100
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition Creature.cpp:3388
Definition Spell.cpp:518
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1261
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2239
uint32 Attributes
Definition SpellInfo.h:324
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1271
void LoadScripts()
Definition Spell.cpp:8499
void cast(bool skipCheck=false)
Definition Spell.cpp:3720
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2195
void SendSpellStart()
Definition Spell.cpp:4666
void TriggerGlobalCooldown()
Definition Spell.cpp:8843
void OnSpellLaunch()
Definition Spell.cpp:8904
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7904
void ReSetTimer()
Definition Spell.h:561
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:718
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4001
bool IsSitState() const
Definition Unit.cpp:16943
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:8927

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEventAtOffset(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, WorldObject::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), sDisableMgr, SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2196{
2197 //==========================================================================================
2198 // Now fill data for trigger system, need know:
2199 // can spell trigger another or not (m_canTrigger)
2200 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2201 //==========================================================================================
2202
2204 // Get data for type of attack and fill base info for trigger
2205 switch (m_spellInfo->DmgClass)
2206 {
2209 if (m_attackType == OFF_ATTACK)
2211 else
2214 break;
2216 // Auto attack
2218 {
2221 }
2222 else // Ranged spell attack
2223 {
2226 }
2227 break;
2228 default:
2231 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2232 {
2235 }
2236 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2237 // Because spell positivity is dependant on target
2238 }
2240
2241 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2243 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2244 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2245 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2246 {
2248 }
2249
2250 /* Effects which are result of aura proc from triggered spell cannot proc
2251 to prevent chain proc of these spells */
2252
2253 // Hellfire Effect - trigger as DOT
2255 {
2258 }
2259
2260 // Ranged autorepeat attack is set as triggered spell - ignore it
2262 {
2269 }
2270 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2273}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition SharedDefines.h:497
@ SPELL_ATTR3_NOT_A_PROC
Definition SharedDefines.h:513
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition SpellDefines.h:148
@ PROC_EX_NONE
Definition SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition SpellMgr.h:141

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8580{
8581 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8582 (*scritr)->_InitHit();
8583}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8754{
8757 {
8758 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8759 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8761 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8762 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8764 }
8765
8768 {
8770 {
8771 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8772 {
8774 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8775 {
8776 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8777 {
8778 m_preCastSpell = 26017;
8779 break;
8780 }
8781 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8782 m_preCastSpell = 67;
8783 }
8784 }
8785 break;
8786 }
8787 case SPELLFAMILY_DRUID:
8788 {
8789 // Faerie Fire (Feral)
8791 m_preCastSpell = 60089;
8792
8793 break;
8794 }
8795 }
8796
8797 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8798 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8799 // and to correctly calculate proc chance when combopoints are present
8801 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8802 {
8803 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8804 continue;
8805 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8806 uint32 auraSpellIdx = (*i)->GetEffIndex();
8807 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8808 {
8809 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8810 // this possibly needs fixing
8811 int32 auraBaseAmount = (*i)->GetBaseAmount();
8812 // proc chance is stored in effect amount
8813 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8814 // build trigger and add to the list
8815 HitTriggerSpell spellTriggerInfo;
8816 spellTriggerInfo.triggeredSpell = spellInfo;
8817 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8818 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8819 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8820 m_hitTriggerSpells.push_back(spellTriggerInfo);
8821 }
8822 }
8823}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition UnitDefines.h:77
@ FORM_BEAR
Definition UnitDefines.h:74
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
922{
925}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:900
uint64 GetDelayStart() const
Definition Spell.h:574

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, WorldObject::m_Events, and EventProcessor::ModifyEventTime().

Referenced by WorldSession::HandleUpdateProjectilePosition().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
561{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2093{
2094 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2095 if (!containerTypeMask)
2096 return;
2097 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2098 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2099 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2100}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2035
Definition GridNotifiers.h:230

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2103{
2104 // max dist for jump target selection
2105 float jumpRadius = 0.0f;
2106 switch (m_spellInfo->DmgClass)
2107 {
2109 // 7.5y for multi shot
2110 jumpRadius = 7.5f;
2111 break;
2113 // 5y for swipe, cleave and similar
2114 jumpRadius = 5.0f;
2115 break;
2118 // 12.5y for chain heal spell since 3.2 patch
2119 if (isChainHeal)
2120 jumpRadius = 12.5f;
2121 // 10y as default for magic chain spells
2122 else
2123 jumpRadius = 10.0f;
2124 break;
2125 }
2126
2127 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2131
2132 // max dist which spell can reach
2133 float searchRadius = jumpRadius;
2134 if (isBouncingFar)
2135 searchRadius *= chainTargets;
2136
2138 std::list<WorldObject*> tempTargets;
2139 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList);
2140 tempTargets.remove(target);
2141
2142 // remove targets which are always invalid for chain spells
2143 // for some spells allow only chain targets in front of caster (swipe for example)
2144 if (!isBouncingFar)
2145 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2146
2147 while (chainTargets)
2148 {
2149 // try to get unit for next chain jump
2150 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2151 // get unit with highest hp deficit in dist
2152 if (isChainHeal)
2153 {
2154 uint32 maxHPDeficit = 0;
2155 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2156 {
2157 if (Unit* unit = (*itr)->ToUnit())
2158 {
2159 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2160 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2161 {
2162 foundItr = itr;
2163 maxHPDeficit = deficit;
2164 }
2165 }
2166 }
2167 }
2168 // get closest object
2169 else
2170 {
2171 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2172 {
2173 if (foundItr == tempTargets.end())
2174 {
2175 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2176 foundItr = itr;
2177 }
2178 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2179 foundItr = itr;
2180 }
2181 }
2182 // not found any valid target - chain ends
2183 if (foundItr == tempTargets.end())
2184 break;
2185
2187 chainSource = *foundItr;
2188
2189 targets.push_back(*foundItr);
2190 tempTargets.erase(foundItr);
2191 --chainTargets;
2192 }
2193}
@ SPELL_ATTR2_CHAIN_FROM_CASTER
Definition SharedDefines.h:479
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition SharedDefines.h:559
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition Spell.cpp:2092
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1407
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1342

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR2_CHAIN_FROM_CASTER, SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2081{
2082 WorldObject* target = nullptr;
2083 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2084 if (!containerTypeMask)
2085 return nullptr;
2086 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2088 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2089 return target;
2090}
Definition GridNotifiers.h:210

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2073{
2074 if (!containerMask)
2075 return;
2076
2077 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2078}

References WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), and Cell::VisitObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
928{
929 if (!targetType.GetTarget())
930 return;
931
932 uint32 effectMask = 1 << effIndex;
933 // set the same target list for all effects
934 // some spells appear to need this, however this requires more research
935 switch (targetType.GetSelectionCategory())
936 {
940 {
941 // targets for effect already selected
942 if (effectMask & processedEffectMask)
943 {
944 return;
945 }
946
947 auto const& effects = GetSpellInfo()->Effects;
948
949 // choose which targets we can select at once
950 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
951 {
952 if (effects[j].IsEffect() &&
953 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
954 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
955 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
956 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
958 {
959 effectMask |= 1 << j;
960 }
961 }
962 processedEffectMask |= effectMask;
963 break;
964 }
965 default:
966 break;
967 }
968
969 switch (targetType.GetSelectionCategory())
970 {
972 SelectImplicitChannelTargets(effIndex, targetType);
973 break;
975 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
976 break;
978 SelectImplicitConeTargets(effIndex, targetType, effectMask);
979 break;
981 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
982 break;
984 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
985 CheckDst();
986
987 SelectImplicitTrajTargets(effIndex, targetType);
988 break;
990 switch (targetType.GetObjectType())
991 {
993 switch (targetType.GetReferenceType())
994 {
997 break;
998 default:
999 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1000 break;
1001 }
1002 break;
1004 switch (targetType.GetReferenceType())
1005 {
1007 SelectImplicitCasterDestTargets(effIndex, targetType);
1008 break;
1010 SelectImplicitTargetDestTargets(effIndex, targetType);
1011 break;
1013 SelectImplicitDestDestTargets(effIndex, targetType);
1014 break;
1015 default:
1016 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1017 break;
1018 }
1019 break;
1020 default:
1021 switch (targetType.GetReferenceType())
1022 {
1024 SelectImplicitCasterObjectTargets(effIndex, targetType);
1025 break;
1027 SelectImplicitTargetObjectTargets(effIndex, targetType);
1028 break;
1029 default:
1030 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1031 break;
1032 }
1033 break;
1034 }
1035 break;
1037 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1038 break;
1039 default:
1040 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1041 break;
1042 }
1043}
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1723
void CheckDst()
Definition Spell.h:503
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1869
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1215
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1686
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1261
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1045
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1806
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1759
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1101
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8714
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1339

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
1953{
1954 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
1956 switch (m_spellInfo->Effects[effIndex].Effect)
1957 {
1961 {
1963
1965
1966 if (target && target->ToPlayer())
1967 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
1968 }
1969 return;
1970 default:
1971 break;
1972 }
1973
1974 // select spell implicit targets based on effect type
1975 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1976 return;
1977
1978 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
1979
1980 if (!targetMask)
1981 return;
1982
1983 WorldObject* target = nullptr;
1984
1985 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1986 {
1987 // add explicit object target or self to the target map
1989 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
1991 {
1993 target = unitTarget;
1994 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
1995 {
1996 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
1997 {
1999 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2000 target = owner;
2001 }
2002 }
2003 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2004 target = m_caster;
2005 }
2006 if (targetMask & TARGET_FLAG_ITEM_MASK)
2007 {
2009 AddItemTarget(itemTarget, 1 << effIndex);
2010 return;
2011 }
2012 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2013 target = m_targets.GetGOTarget();
2014 break;
2015 // add self to the target map
2017 if (targetMask & TARGET_FLAG_UNIT_MASK)
2018 target = m_caster;
2019 break;
2020 default:
2021 break;
2022 }
2023
2025
2026 if (target)
2027 {
2028 if (target->ToUnit())
2029 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2030 else if (target->ToGameObject())
2031 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2032 }
2033}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition SpellInfo.h:72
GameObject * ToGameObject()
Definition Object.h:213
Corpse * GetCorpseTarget() const
Definition Spell.cpp:293
Definition SpellInfo.h:217
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2417
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2284
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2479
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8686

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
788{
789 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
790 if (Unit* target = m_targets.GetUnitTarget())
791 {
792 // check for explicit target redirection, for Grounding Totem for example
796 {
797 Unit* redirect;
798 switch (m_spellInfo->DmgClass)
799 {
802 break;
806 break;
807 default:
808 redirect = nullptr;
809 break;
810 }
811 if (redirect && (redirect != target))
812 {
813 m_targets.SetUnitTarget(redirect);
815 }
816 }
817 }
818}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition Unit.cpp:11273
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:11235

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1262{
1263 Unit* referer = nullptr;
1264 switch (targetType.GetReferenceType())
1265 {
1269 referer = m_caster;
1270 break;
1272 referer = m_targets.GetUnitTarget();
1273 break;
1275 {
1276 // find last added target for this effect
1277 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1278 {
1279 if (ihit->effectMask & (1 << effIndex))
1280 {
1281 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1282 break;
1283 }
1284 }
1285 break;
1286 }
1287 default:
1288 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1289 return;
1290 }
1291 if (!referer)
1292 return;
1293
1294 Position const* center = nullptr;
1295 switch (targetType.GetReferenceType())
1296 {
1298 center = m_targets.GetSrcPos();
1299 break;
1301 center = m_targets.GetDstPos();
1302 break;
1306 center = referer;
1307 break;
1308 default:
1309 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1310 return;
1311 }
1312
1313 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1314 std::list<WorldObject*> targets;
1315 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1316 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1317
1318 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1319
1320 if (!targets.empty())
1321 {
1322 // Other special target selection goes here
1323 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1324 {
1326 Acore::Containers::RandomResize(targets, maxTargets);
1327 }
1328
1329 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1330 {
1331 if (Unit* unitTarget = (*itr)->ToUnit())
1332 AddUnitTarget(unitTarget, effMask, false);
1333 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1334 AddGOTarget(gObjTarget, effMask);
1335 }
1336 }
1337}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:91
Position const * GetSrcPos() const
Definition Spell.cpp:361
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8672
int32 GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:6233
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:79
float RadiusMod
Definition Spell.h:225
uint32 MaxAffectedTargets
Definition Spell.h:224

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), Unit::GetTotalAuraModifierByAffectMask(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1340{
1342
1343 switch (targetType.GetTarget())
1344 {
1345 case TARGET_DEST_CASTER:
1347 break;
1348 case TARGET_DEST_HOME:
1349 if (Player* playerCaster = m_caster->ToPlayer())
1350 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1351 break;
1352 case TARGET_DEST_DB:
1353 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1354 {
1357 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1358 else if (st->target_mapId == m_caster->GetMapId())
1359 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1360 }
1361 else
1362 {
1363 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1364 if (WorldObject* target = m_targets.GetObjectTarget())
1365 dest = SpellDestination(*target);
1366 }
1367 break;
1369 {
1370 float min_dis = m_spellInfo->GetMinRange(true);
1371 float max_dis = m_spellInfo->GetMaxRange(true);
1372 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1373 float x, y, z, angle;
1374 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1375 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1377
1378 float ground = m_caster->GetMapHeight(x, y, z, true);
1379 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1380 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
1381 if (liquidData.Status)
1382 liquidLevel = liquidData.Level;
1383
1384 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1385 {
1388 finish(false);
1389 return;
1390 }
1391
1392 if (ground + 0.75 > liquidLevel)
1393 {
1396 finish(false);
1397 return;
1398 }
1399
1400 if (!m_caster->IsWithinLOS(x, y, z))
1401 {
1404 finish(false);
1405 return;
1406 }
1407
1408 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1409 break;
1410 }
1412 {
1413 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1414 Map* map = m_caster->GetMap();
1415 uint32 mapid = m_caster->GetMapId();
1416 uint32 phasemask = m_caster->GetPhaseMask();
1417 float collisionHeight = m_caster->GetCollisionHeight();
1418 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1419
1420 Position pos;
1421 Position lastpos;
1422 m_caster->GetPosition(startx, starty, startz, starto);
1423 pos.Relocate(startx, starty, startz, starto);
1424 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1425 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1426
1427 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1428 // the Z position may be slightly below the vmap ground level.
1429 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1430 // beneath the actual surface.
1431 //
1432 // Example:
1433 // actual vmap ground: -56.342392
1434 // Z position: -56.347195
1435 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1436 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1437
1438 bool isCasterInWater = m_caster->IsInWater();
1439 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1440 {
1441 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1442 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1443 float maxtravelDistZ = 2.65f;
1444 float overdistance = 0.0f;
1445 float totalpath = 0.0f;
1446 float beforewaterz = 0.0f;
1447 bool inwater = false;
1448 bool wcol = false;
1449 const float step = 2.0f;
1450 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1451 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1452 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1453 int j = 1;
1454 for (; j < (numChecks + 1); j++)
1455 {
1456 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1457 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1458 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1459 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1460
1461 if (j < 2)
1462 {
1463 prevZ = pos.GetPositionZ();
1464 }
1465 else
1466 {
1467 prevZ = tstZ;
1468 }
1469
1470 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1471 ground = tstZ;
1472
1473 if (!isCasterInWater)
1474 {
1475 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1476 {
1477 if (!(beforewaterz != 0.0f))
1478 {
1479 beforewaterz = prevZ;
1480 }
1481 tstZ = beforewaterz;
1482 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1483 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1484 }
1485 }
1486 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1487 {
1488 prevZ = pos.GetPositionZ();
1489 tstZ = pos.GetPositionZ();
1490 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1491
1492 inwater = true;
1493 if (inwater && (fabs(tstZ - ground) < 2.0f))
1494 {
1495 wcol = true;
1496 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1497 }
1498
1499 // if (j < 2)
1500 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1501 // else
1502 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1503 }
1504
1505 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1506 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1507 {
1508 if (inwater && !IsInWater)
1509 inwater = false;
1510
1511 // highest available point
1512 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1513 // upper or floor
1514 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1515 //lower than floor
1516 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1517
1518 //distance of rays, will select the shortest in 3D
1519 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1520 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1521 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1522 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1523 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1524 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1525
1526 if (srange1 < srange2)
1527 {
1528 tstZ = tstZ1;
1529 srange = srange1;
1530 }
1531 else if (srange3 < srange2)
1532 {
1533 tstZ = tstZ3;
1534 srange = srange3;
1535 }
1536 else
1537 {
1538 tstZ = tstZ2;
1539 srange = srange2;
1540 }
1541
1542 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1543 }
1544
1545 destx = tstX;
1546 desty = tstY;
1547 destz = tstZ;
1548
1549 totalpath += srange;
1550
1551 if (totalpath > distance)
1552 {
1553 overdistance = totalpath - distance;
1554 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1555 }
1556
1557 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1558 // check dynamic collision
1559 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1560
1561 // collision occured
1562 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1563 {
1564 if ((overdistance > 0.0f) && (overdistance < 1.f))
1565 {
1566 destx = prevX + overdistance * cos(pos.GetOrientation());
1567 desty = prevY + overdistance * sin(pos.GetOrientation());
1568 //LOG_ERROR("spells", "(collision) collision occured 1");
1569 }
1570 else
1571 {
1572 // move back a bit
1573 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1574 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1575 //LOG_ERROR("spells", "(collision) collision occured 2");
1576 }
1577
1578 // highest available point
1579 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1580 // upper or floor
1581 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1582 //lower than floor
1583 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1584
1585 //distance of rays, will select the shortest in 3D
1586 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1587 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1588 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1589
1590 if (srange1 < srange2)
1591 destz = destz1;
1592 else if (srange3 < srange2)
1593 destz = destz3;
1594 else
1595 destz = destz2;
1596
1597 if (inwater && destz < prevZ && !wcol)
1598 destz = prevZ;
1599 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1600
1601 // Don't make the player move backward from the xy adjustments by collisions.
1602 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1603 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1604 {
1605 destx = startx;
1606 desty = starty;
1607 destz = startz;
1608 }
1609
1610 break;
1611 }
1612 // we have correct destz now
1613 }
1614
1615 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1616 dest = SpellDestination(lastpos);
1617 }
1618 else
1619 {
1620 float z = pos.GetPositionZ();
1621 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1622 // check dynamic collision
1623 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1624
1625 // collision occured
1626 if (col || dcol)
1627 {
1628 // move back a bit
1629 destx = destx - (0.6 * cos(pos.GetOrientation()));
1630 desty = desty - (0.6 * sin(pos.GetOrientation()));
1631 }
1632
1633 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1634 dest = SpellDestination(lastpos);
1635 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1636 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1637 }
1638 break;
1639 }
1640 default:
1641 {
1642 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1643 float angle = targetType.CalcDirectionAngle();
1644 float objSize = m_caster->GetCombatReach();
1645
1646 switch (targetType.GetTarget())
1647 {
1649 dist = PET_FOLLOW_DIST;
1650 break;
1652 if (dist > objSize)
1653 dist = objSize + (dist - objSize) * float(rand_norm());
1654 break;
1659 {
1660 static float const DefaultTotemDistance = 3.0f;
1661 if (!m_spellInfo->Effects[effIndex].HasRadius())
1662 dist = DefaultTotemDistance;
1663 break;
1664 }
1665 default:
1666 break;
1667 }
1668
1669 if (dist < objSize)
1670 {
1671 dist = objSize;
1672 }
1673
1674 Position pos = dest._position;
1675 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1676
1677 dest.Relocate(pos);
1678 break;
1679 }
1680 }
1681
1682 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1683 m_targets.SetDst(dest);
1684}
#define VMAP_INVALID_HEIGHT_VALUE
Definition IVMapMgr.h:49
@ SPELL_EFFECT_BIND
Definition SharedDefines.h:800
@ SPELL_EFFECT_TELEPORT_UNITS
Definition SharedDefines.h:794
@ TARGET_DEST_CASTER_RANDOM
Definition SharedDefines.h:1487
@ TARGET_DEST_DB
Definition SharedDefines.h:1433
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1470
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1459
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1457
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1454
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1458
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1447
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1434
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1456
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1451
@ TARGET_DEST_HOME
Definition SharedDefines.h:1429
float const GROUND_HEIGHT_TOLERANCE
Definition SharedDefines.h:26
@ SPELL_FAILED_TOO_SHALLOW
Definition SharedDefines.h:1116
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:381
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional< uint8 > ReqLiquidType)
Definition Map.cpp:1297
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1145
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1594
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition Map.cpp:1572
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8700
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:21209
static VMapMgr2 * createOrGetVMapMgr()
Definition VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3056
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition Object.cpp:2663
Definition GridTerrainData.h:199
float Level
Definition GridTerrainData.h:204
LiquidStatus Status
Definition GridTerrainData.h:206
Definition SpellMgr.h:389

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), GROUND_HEIGHT_TOLERANCE, SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1760{
1761 WorldObject* target = nullptr;
1762 bool checkIfValid = true;
1763
1764 switch (targetType.GetTarget())
1765 {
1766 case TARGET_UNIT_CASTER:
1767 target = m_caster;
1768 checkIfValid = false;
1769 break;
1770 case TARGET_UNIT_MASTER:
1771 target = m_caster->GetCharmerOrOwner();
1772 break;
1773 case TARGET_UNIT_PET:
1774 target = m_caster->GetGuardianPet();
1775 if (!target)
1776 target = m_caster->GetCharm();
1777 break;
1779 if (m_caster->IsSummon())
1780 target = m_caster->ToTempSummon()->GetSummonerUnit();
1781 break;
1783 target = m_caster->GetVehicleBase();
1784 break;
1794 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1795 break;
1796 default:
1797 break;
1798 }
1799
1800 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1801
1802 if (target && target->ToUnit())
1803 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1804}
@ TARGET_UNIT_PASSENGER_1
Definition SharedDefines.h:1512
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1517
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1509
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1513
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1515
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1518
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1442
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1516
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1514
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1507
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1511
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition Unit.cpp:19000
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:229

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1829{
1830 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1831 if (Player* modOwner = m_caster->GetSpellModOwner())
1832 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1833
1834 if (maxTargets > 1)
1835 {
1836 // mark damage multipliers as used
1837 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1838 if (effMask & (1 << k))
1839 m_damageMultipliers[k] = 1.0f;
1840 m_applyMultiplierMask |= effMask;
1841
1842 std::list<WorldObject*> targets;
1843 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1844 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1845
1846 // Chain primary target is added earlier
1847 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1848
1849 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1850 if (Unit* unitTarget = (*itr)->ToUnit())
1851 AddUnitTarget(unitTarget, effMask, false);
1852 }
1853}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1460
@ SPELLMOD_JUMP_TARGETS
Definition SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition Spell.cpp:2102

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1046{
1047 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1048 {
1049 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1050 return;
1051 }
1052
1053 switch (targetType.GetTarget())
1054 {
1056 {
1057 // Xinef: All channel selectors have needed data passed in m_targets structure
1059 if (target)
1060 {
1061 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1062 // unit target may be no longer avalible - teleported out of map for example
1063 if (target && target->ToUnit())
1064 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1065 }
1066 else
1067 {
1068 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1069 }
1070 break;
1071 }
1076 {
1077 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1078 if (target)
1079 m_targets.SetDst(*target);
1080 }
1082 {
1083 if (channeledSpell->m_targets.GetUnitTarget())
1084 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1085 }
1086 else //if (!m_targets.HasDst())
1087 {
1088 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1089 }
1090 break;
1092 if (GetOriginalCaster())
1094 break;
1095 default:
1096 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1097 break;
1098 }
1099}
@ TARGET_DEST_CHANNEL_TARGET
Definition SharedDefines.h:1491
@ TARGET_UNIT_CHANNEL_TARGET
Definition SharedDefines.h:1492
@ TARGET_DEST_CHANNEL_CASTER
Definition SharedDefines.h:1521
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition Spell.cpp:463
SpellDestination const * GetDstChannel() const
Definition Spell.cpp:473
bool HasDstChannel() const
Definition Spell.cpp:468

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1216{
1217 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1218 {
1219 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1220 return;
1221 }
1222 std::list<WorldObject*> targets;
1223 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1224 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1225 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1226 float coneAngle = M_PI / 2;
1227 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1228
1229 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1230 {
1231 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1232 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1233 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1234
1235 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1236
1237 if (!targets.empty())
1238 {
1239 // Other special target selection goes here
1240 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1241 {
1243 Acore::Containers::RandomResize(targets, maxTargets);
1244 }
1245
1246 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1247 {
1248 if (Unit* unit = (*itr)->ToUnit())
1249 {
1250 AddUnitTarget(unit, effMask, false);
1251 }
1252 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1253 {
1254 AddGOTarget(gObjTarget, effMask);
1255 }
1256 }
1257 }
1258 }
1259}
SpellTargetCheckTypes
Definition SpellInfo.h:113
SpellTargetObjectTypes
Definition SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), Unit::GetTotalAuraModifierByAffectMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1724{
1725 // set destination to caster if no dest provided
1726 // can only happen if previous destination target could not be set for some reason
1727 // (not found nearby target, or channel target for example
1728 // maybe we should abort the spell in such case?
1729 CheckDst();
1730
1732
1733 switch (targetType.GetTarget())
1734 {
1738 case TARGET_DEST_DEST:
1739 return;
1740 default:
1741 {
1742 float angle = targetType.CalcDirectionAngle();
1743 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1744 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1745 dist *= float(rand_norm());
1746
1747 Position pos = dest._position;
1748 m_caster->MovePosition(pos, dist, angle);
1749
1750 dest.Relocate(pos);
1751 break;
1752 }
1753 }
1754
1755 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1756 m_targets.ModDst(dest);
1757}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1443
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1501
@ TARGET_DEST_DEST
Definition SharedDefines.h:1502
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1503
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1444
void ModDst(Position const &pos)
Definition Spell.cpp:435
SpellDestination const * GetDst() const
Definition Spell.cpp:395
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2813

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, and TARGET_DEST_DYNOBJ_NONE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1102{
1103 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1104 {
1105 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1106 return;
1107 }
1108
1109 float range = 0.0f;
1110 switch (targetType.GetCheckType())
1111 {
1112 case TARGET_CHECK_ENEMY:
1113 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1114 break;
1115 case TARGET_CHECK_ALLY:
1116 case TARGET_CHECK_PARTY:
1117 case TARGET_CHECK_RAID:
1119 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1120 break;
1121 case TARGET_CHECK_ENTRY:
1124 break;
1125 default:
1126 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1127 break;
1128 }
1129
1130 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1131
1132 // handle emergency case - try to use other provided targets if no conditions provided
1133 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1134 {
1135 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1136 switch (targetType.GetObjectType())
1137 {
1140 {
1141 if (focusObject)
1142 AddGOTarget(focusObject, effMask);
1143 return;
1144 }
1145 break;
1148 {
1149 if (focusObject)
1151 return;
1152 }
1153 break;
1154 default:
1155 break;
1156 }
1157 }
1158
1159 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1160 if (!target)
1161 {
1162 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1163 return;
1164 }
1165
1166 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1167 if (!target)
1168 {
1169 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1170 return;
1171 }
1172
1173 switch (targetType.GetObjectType())
1174 {
1176 {
1177 if (Unit* unit = target->ToUnit())
1178 {
1179 AddUnitTarget(unit, effMask, true, false);
1180 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1181 // and if channeled spell has target 77, it requires unitTarget, set it here!
1182 // xinef: if we have NO unit target
1183 if (!m_targets.GetUnitTarget())
1184 {
1186 }
1187 }
1188 else
1189 {
1190 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1191 return;
1192 }
1193 break;
1194 }
1196 if (GameObject* gobjTarget = target->ToGameObject())
1197 AddGOTarget(gobjTarget, effMask);
1198 else
1199 {
1200 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1201 return;
1202 }
1203 break;
1205 m_targets.SetDst(*target);
1206 break;
1207 default:
1208 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1209 break;
1210 }
1211
1212 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1213}
@ TARGET_CHECK_PARTY
Definition SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition Spell.cpp:2080
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1828

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1687{
1689
1690 SpellDestination dest(*target);
1691
1692 switch (targetType.GetTarget())
1693 {
1696 break;
1697 default:
1698 {
1699 float angle = targetType.CalcDirectionAngle();
1700 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1701 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1702 {
1703 dist *= float(rand_norm());
1704 }
1705
1706 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1707 {
1709 }
1710
1711 Position pos = dest._position;
1712 target->MovePositionToFirstCollision(pos, dist, angle);
1713
1714 dest.Relocate(pos);
1715 break;
1716 }
1717 }
1718
1719 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1720 m_targets.SetDst(dest);
1721}
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1478
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1480
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1489
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1468
@ UNIT_FIELD_BOUNDINGRADIUS
Definition UpdateFields.h:122

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1807{
1808 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1809
1811
1812 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1813
1814 if (target)
1815 {
1816 if (Unit* unit = target->ToUnit())
1817 AddUnitTarget(unit, 1 << effIndex, true, false);
1818 else if (GameObject* gobj = target->ToGameObject())
1819 AddGOTarget(gobj, 1 << effIndex);
1820
1821 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1822 }
1823 // Script hook can remove object target and we would wrongly land here
1824 else if (Item* item = m_targets.GetItemTarget())
1825 AddItemTarget(item, 1 << effIndex);
1826}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1870{
1871 if (!m_targets.HasTraj())
1872 return;
1873
1874 float dist2d = m_targets.GetDist2d();
1875 if (!dist2d)
1876 return;
1877
1878 Position srcPos = *m_targets.GetSrcPos();
1880 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
1881
1882 std::list<WorldObject*> targets;
1883 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1885 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
1886 if (targets.empty())
1887 return;
1888
1890
1891 float b = tangent(m_targets.GetElevation());
1892 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1893 if (a > -0.0001f)
1894 a = 0.f;
1895
1896 // We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
1897 // limit max range to 300 yards, sometimes triggered spells can have 50000yds
1898 float bestDist = m_spellInfo->GetMaxRange(false);
1899 if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell))
1900 bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
1901
1902 // GameObjects don't cast traj
1903 Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
1904 for (auto itr = targets.begin(); itr != targets.end(); ++itr)
1905 {
1906 if (m_spellInfo->CheckTarget(unitCaster, *itr, true) != SPELL_CAST_OK)
1907 continue;
1908
1909 if (Unit* unit = (*itr)->ToUnit())
1910 {
1911 if (unitCaster == *itr || unitCaster->IsOnVehicle(unit) || unit->GetVehicle())
1912 continue;
1913
1914 if (Creature* creatureTarget = unit->ToCreature())
1915 {
1916 if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES))
1917 continue;
1918 }
1919 }
1920
1921 float const size = std::max((*itr)->GetCombatReach(), 1.0f);
1922 float const objDist2d = srcPos.GetExactDist2d(*itr);
1923 float const dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
1924
1925 float const horizontalDistToTraj = std::fabs(objDist2d * std::sin(srcPos.GetRelativeAngle(*itr)));
1926 float const sizeFactor = std::cos((horizontalDistToTraj / size) * (M_PI / 2.0f));
1927 float const distToHitPoint = std::max(objDist2d * std::cos(srcPos.GetRelativeAngle(*itr)) - size * sizeFactor, 0.0f);
1928 float const height = distToHitPoint * (a * distToHitPoint + b);
1929
1930 if (fabs(dz - height) > size + b / 2.0f + TRAJECTORY_MISSILE_SIZE)
1931 continue;
1932
1933 if (distToHitPoint < bestDist)
1934 {
1935 bestDist = distToHitPoint;
1936 break;
1937 }
1938 }
1939
1940 if (dist2d > bestDist)
1941 {
1942 float x = m_targets.GetSrcPos()->m_positionX + std::cos(unitCaster->GetOrientation()) * bestDist;
1943 float y = m_targets.GetSrcPos()->m_positionY + std::sin(unitCaster->GetOrientation()) * bestDist;
1944 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1945
1946 SpellDestination dest(x, y, z, unitCaster->GetOrientation());
1947 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1948 m_targets.ModDst(dest);
1949 }
1950}
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:85
@ CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES
Definition SharedDefines.h:2715
float tangent(float x)
Definition Spell.cpp:1855
#define TRAJECTORY_MISSILE_SIZE
Definition Spell.h:42
Definition Object.h:795
float GetElevation() const
Definition Spell.h:178
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1906
void SetOrientation(float orientation)
Definition Position.h:116

References ASSERT_NOTNULL, CallScriptDestinationTargetSelectHandlers(), SpellInfo::CheckTarget(), CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES, SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::SetOrientation(), SPELL_CAST_OK, sSpellMgr, tangent(), Object::ToCreature(), Object::ToUnit(), and TRAJECTORY_MISSILE_SIZE.

Referenced by SelectEffectImplicitTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
821{
822 // select targets for cast phase
824
825 uint32 processedAreaEffectsMask = 0;
826 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
827 {
828 // not call for empty effect.
829 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
830 if (!m_spellInfo->Effects[i].IsEffect())
831 continue;
832
833 // set expected type of implicit targets to be sent to client
834 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
835 if (implicitTargetMask & TARGET_FLAG_UNIT)
837 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
839
840 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
841 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
842
843 // Select targets of effect based on effect type
844 // those are used when no valid target could be added for spell effect based on spell target type
845 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
846 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
847 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
849
850 if (m_targets.HasDst())
852
854 {
855 // maybe do this for all spells?
856 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
857 {
859 finish(false);
860 return;
861 }
862
863 uint8 mask = (1 << i);
864 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
865 {
866 if (ihit->effectMask & mask)
867 {
869 break;
870 }
871 }
872 }
873 else if (m_auraScaleMask)
874 {
875 bool checkLvl = !m_UniqueTargetInfo.empty();
876 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
877 {
878 // remove targets which did not pass min level check
879 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
880 {
881 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
882 return true;
883 }
884
885 return false;
886 }), std::end(m_UniqueTargetInfo));
887
888 if (checkLvl && m_UniqueTargetInfo.empty())
889 {
891 finish(false);
892 }
893 }
894 }
895
896 if (uint64 dstDelay = CalculateDelayMomentForDst())
897 m_delayMoment = dstDelay;
898}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:31
@ TARGET_FLAG_GAMEOBJECT
Definition SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition Spell.h:130
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition Spell.cpp:927
void SelectExplicitTargets()
Definition Spell.cpp:787
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition Spell.cpp:2508
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:1952

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4619{
4620 if (result == SPELL_CAST_OK)
4621 return;
4622
4623 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4624 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4625
4626 caster->SendDirectMessage(&data);
4627}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4513
@ SMSG_CAST_FAILED
Definition Opcodes.h:334

References Player::SendDirectMessage(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_the_cleansing_shrine_cast::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4630{
4631 if (result == SPELL_CAST_OK)
4632 return;
4633
4634 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4635 return;
4636
4637 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4638 return;
4639
4640 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4642 result = SPELL_FAILED_DONT_REPORT;
4643
4645}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition SharedDefines.h:1119
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition SpellDefines.h:149
bool IsCharmed() const
Definition Unit.h:1295

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5156{
5157 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5158 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5159 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5160 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5161
5162 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5163 data << m_caster->GetPackGUID();
5164 data << uint32(m_spellInfo->Id);
5165 data << uint32(duration);
5166
5167 m_caster->SendMessageToSet(&data, true);
5168
5171
5172 m_timer = duration;
5173 if (channelTarget)
5175
5177}
@ MSG_CHANNEL_START
Definition Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5124{
5125 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5126 data << m_caster->GetPackGUID();
5127 data << uint8(m_cast_count);
5128 data << uint32(m_spellInfo->Id);
5129 data << uint8(result);
5130 m_caster->SendMessageToSet(&data, true);
5131
5132 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5133 data << m_caster->GetPackGUID();
5134 data << uint8(m_cast_count);
5135 data << uint32(m_spellInfo->Id);
5136 data << uint8(result);
5137 m_caster->SendMessageToSet(&data, true);
5138}
@ SMSG_SPELL_FAILURE
Definition Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5023{
5024 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5025
5026 data << m_caster->GetPackGUID();
5027
5028 data << uint32(m_spellInfo->Id);
5029
5030 uint8 effCount = 0;
5031 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5032 {
5033 if (m_effectExecuteData[i])
5034 ++effCount;
5035 }
5036
5037 if (!effCount)
5038 return;
5039
5040 data << uint32(effCount);
5041 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5042 {
5043 if (!m_effectExecuteData[i])
5044 continue;
5045
5046 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5047
5048 data.append(*m_effectExecuteData[i]);
5049
5050 delete m_effectExecuteData[i];
5051 m_effectExecuteData[i] = nullptr;
5052 }
5053 m_caster->SendMessageToSet(&data, true);
5054}
@ SMSG_SPELLLOGEXECUTE
Definition Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2013{
2014 Player* player = m_caster->ToPlayer();
2015 if (!player)
2016 return;
2017
2018 if (gameObjTarget)
2019 {
2020 // Players shouldn't be able to loot gameobjects that are currently despawned
2021 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2022 {
2023 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2024 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2025 return;
2026 }
2027 // special case, already has GossipHello inside so return and avoid calling twice
2029 {
2031 return;
2032 }
2033
2034 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2035 return;
2036
2037 if (gameObjTarget->AI()->GossipHello(player, false))
2038 return;
2039
2040 switch (gameObjTarget->GetGoType())
2041 {
2043 gameObjTarget->UseDoorOrButton(0, false, player);
2044 return;
2046 gameObjTarget->UseDoorOrButton(0, false, player);
2047
2048 // Xinef: properly link possible traps
2049 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2050 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2051 return;
2055 return;
2056
2058 // triggering linked GO
2061 return;
2062
2064 // triggering linked GO
2065 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2067
2068 // Don't return, let loots been taken
2069 default:
2070 break;
2071 }
2072 }
2073
2074 // Send loot
2075 player->SendLoot(guid, loottype);
2076}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1579
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1573
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
bool isSpawned() const
Definition GameObject.h:189
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1350
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:214
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
uint32 gossipID
Definition GameObjectData.h:72
uint32 linkedTrap
Definition GameObjectData.h:59
struct GameObjectTemplate::@235::@240 chest
struct GameObjectTemplate::@235::@239 questgiver
uint32 linkedTrapId
Definition GameObjectData.h:90
struct GameObjectTemplate::@235::@244 spellFocus

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4648{
4649 if (result == SPELL_CAST_OK)
4650 return;
4651
4652 Unit* owner = m_caster->GetCharmerOrOwner();
4653 if (!owner)
4654 return;
4655
4656 Player* player = owner->ToPlayer();
4657 if (!player)
4658 return;
4659
4660 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4662
4663 player->SendDirectMessage(&data);
4664}
@ SMSG_PET_CAST_FAILED
Definition Opcodes.h:342

References Unit::GetCharmerOrOwner(), m_cast_count, m_caster, m_customError, m_spellInfo, Player::SendDirectMessage(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5180{
5181 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5182 // for player resurrections the name is looked up by guid
5183 std::string const sentName(m_caster->IsPlayer()
5184 ? ""
5185 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5186
5187 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5188 data << m_caster->GetGUID();
5189 data << uint32(sentName.size() + 1);
5190
5191 data << sentName;
5192 data << uint8(0); // null terminator
5193
5194 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5195 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5197 data << uint32(0);
5198 target->SendDirectMessage(&data);
5199}
@ SPELL_ATTR3_NO_RES_TIMER
Definition SharedDefines.h:508
@ SMSG_RESURRECT_REQUEST
Definition Opcodes.h:377

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, Player::SendDirectMessage(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4295{
4296 // xinef: properly add creature cooldowns
4297 if (!m_caster->IsPlayer())
4298 {
4300 {
4301 // xinef: this should be added here
4302 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4303
4304 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4307 {
4308 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4309 data << m_caster->GetGUID();
4311 data << uint32(m_spellInfo->Id);
4313 player->SendDirectMessage(&data);
4314 }
4315 }
4316 return;
4317 }
4318
4319 Player* _player = m_caster->ToPlayer();
4320
4321 // mana/health/etc potions, disabled by client (until combat out as declarate)
4323 {
4324 // need in some way provided data for Spell::finish SendCooldownEvent
4325 _player->SetLastPotionId(m_CastItem->GetEntry());
4326 return;
4327 }
4328
4329 // have infinity cooldown but set at aura apply
4330 // do not set cooldown for triggered spells (needed by reincarnation)
4335 return;
4336
4338}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition Unit.h:620
void SetLastPotionId(uint32 item_id)
Definition Player.h:1827
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:10876
uint32 RecoveryTime
Definition SpellInfo.h:348
bool RequireCooldownInfo() const
Definition SpellInfo.cpp:1182
@ SMSG_SPELL_COOLDOWN
Definition Opcodes.h:338

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4747{
4748 // not send invisible spell casting
4749 if (!IsNeedSendToClient(true))
4750 return;
4751
4752 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4753
4754 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4755
4756 // triggered spells with spell visual != 0
4758 castFlags |= CAST_FLAG_PENDING;
4759
4761 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4762
4763 // should only be sent to self, but the current messaging doesn't make that possible
4764 if (m_caster->IsPlayer() || m_caster->IsPet())
4765 {
4766 switch (m_spellInfo->PowerType)
4767 {
4768 case POWER_HEALTH:
4769 break;
4770 case POWER_RUNE:
4771 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4772 break;
4773 default:
4774 if (m_powerCost != 0)
4775 {
4776 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4777 }
4778 break;
4779 }
4780 }
4781
4782 if ((m_caster->IsPlayer())
4786 {
4787 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4788 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4789 }
4790
4792 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4793
4794 if (m_targets.HasTraj())
4795 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4796
4798 castFlags |= CAST_FLAG_NO_GCD;
4799
4800 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4801 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4802 {
4803 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4804 {
4805 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4806 {
4807 realCasterGUID = casterGameobject->GetPackGUID();
4808 }
4809 }
4810 }
4811
4812 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4813
4814 if (m_CastItem)
4815 data << m_CastItem->GetPackGUID();
4816 else
4817 data << realCasterGUID;
4818
4819 data << realCasterGUID;
4820 data << uint8(m_cast_count); // pending spell cast?
4821 data << uint32(m_spellInfo->Id); // spellId
4822 data << uint32(castFlags); // cast flags
4823 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4824
4825 WriteSpellGoTargets(&data);
4826
4827 m_targets.Write(data);
4828
4829 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4831
4832 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4833 {
4834 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4835 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4836 if (Player* player = m_caster->ToPlayer())
4837 {
4838 uint8 runeMaskInitial = m_runesState;
4839 uint8 runeMaskAfterCast = player->GetRunesState();
4840 data << uint8(runeMaskInitial); // runes state before
4841 data << uint8(runeMaskAfterCast); // runes state after
4842 for (uint8 i = 0; i < MAX_RUNES; ++i)
4843 {
4844 uint8 mask = (1 << i);
4845 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4846 {
4847 // float casts ensure the division is performed on floats as we need float result
4848 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4849 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4850 }
4851 }
4852 }
4853 }
4854 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4855 {
4856 data << m_targets.GetElevation();
4858 }
4859
4860 if (castFlags & CAST_FLAG_PROJECTILE)
4861 WriteAmmoToPacket(&data);
4862
4863 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4864 {
4865 data << uint32(0);
4866 data << uint32(0);
4867 }
4868
4870 {
4871 data << uint8(0);
4872 }
4873
4874 m_caster->SendMessageToSet(&data, true);
4875}
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition SharedDefines.h:935
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition SharedDefines.h:394
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition Spell.h:66
@ CAST_FLAG_ADJUST_MISSILE
Definition Spell.h:64
@ CAST_FLAG_UNKNOWN_9
Definition Spell.h:55
@ CAST_FLAG_NO_GCD
Definition Spell.h:65
@ CAST_FLAG_PROJECTILE
Definition Spell.h:52
@ CAST_FLAG_POWER_LEFT_SELF
Definition Spell.h:58
@ CAST_FLAG_RUNE_LIST
Definition Spell.h:68
@ CAST_FLAG_PENDING
Definition Spell.h:47
Definition ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition Spell.cpp:178
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:347
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition Spell.cpp:4962
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:4877
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8084
@ SMSG_SPELL_GO
Definition Opcodes.h:336
int32 CastTime
Definition DBCStructure.h:1760

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4667{
4668 if (!IsNeedSendToClient(false))
4669 return;
4670
4671 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4672
4673 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4674
4676 castFlags |= CAST_FLAG_PENDING;
4677
4679 castFlags |= CAST_FLAG_PROJECTILE;
4680
4681 if (m_caster->IsPlayer() || m_caster->IsPet())
4682 {
4683 switch (m_spellInfo->PowerType)
4684 {
4685 case POWER_HEALTH:
4686 break;
4687 case POWER_RUNE:
4688 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4689 break;
4690 default:
4691 if (m_powerCost != 0)
4692 {
4693 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4694 }
4695 break;
4696 }
4697 }
4698
4700 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4701
4702 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4703 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4704 {
4705 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4706 {
4707 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4708 {
4709 realCasterGUID = casterGameobject->GetPackGUID();
4710 }
4711 }
4712 }
4713
4714 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4715 if (m_CastItem)
4716 data << m_CastItem->GetPackGUID();
4717 else
4718 data << realCasterGUID;
4719
4720 data << realCasterGUID;
4721 data << uint8(m_cast_count); // pending spell cast?
4722 data << uint32(m_spellInfo->Id); // spellId
4723 data << uint32(castFlags); // cast flags
4724 data << int32(m_timer); // delay?
4725
4726 m_targets.Write(data);
4727
4728 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4730
4731 if (castFlags & CAST_FLAG_PROJECTILE)
4732 WriteAmmoToPacket(&data);
4733
4734 if (castFlags & CAST_FLAG_UNKNOWN_23)
4735 {
4736 data << uint32(0);
4737 data << uint32(0);
4738 }
4739
4740 m_caster->SendMessageToSet(&data, true);
4741
4744}
@ CAST_FLAG_UNKNOWN_23
Definition Spell.h:69
@ CAST_FLAG_HAS_TRAJECTORY
Definition Spell.h:48
@ SMSG_SPELL_START
Definition Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
560{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
575{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
573{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8427{
8428 switch (mod)
8429 {
8431 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8432 break;
8434 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8435 break;
8437 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8438 break;
8440 m_spellValue->RadiusMod = (float)value / 10000;
8441 break;
8444 break;
8447 break;
8449 m_spellValue->AuraDuration = value;
8450 break;
8452 m_spellValue->ForcedCritResult = (bool)value;
8453 break;
8455 m_spellValue->MiscVal[0] = value;
8456 break;
8458 m_spellValue->MiscVal[1] = value;
8459 break;
8461 m_spellValue->MiscVal[2] = value;
8462 break;
8463 }
8464}
@ SPELLVALUE_AURA_STACK
Definition SpellDefines.h:118
@ SPELLVALUE_MISCVALUE1
Definition SpellDefines.h:122
@ SPELLVALUE_AURA_DURATION
Definition SpellDefines.h:119
@ SPELLVALUE_MISCVALUE2
Definition SpellDefines.h:123
@ SPELLVALUE_RADIUS_MOD
Definition SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition SpellDefines.h:120
@ SPELLVALUE_MISCVALUE0
Definition SpellDefines.h:121
bool ForcedCritResult
Definition Spell.h:228

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::MiscVal, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, SPELLVALUE_MISCVALUE0, SPELLVALUE_MISCVALUE1, SPELLVALUE_MISCVALUE2, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
494{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5971{
5972 Unit* caster = m_originalCaster;
5973 if (!caster)
5974 return;
5975
5976 if (caster->IsTotem())
5977 caster = caster->ToTotem()->GetOwner();
5978
5979 // in another case summon new
5980 uint8 summonLevel = caster->GetLevel();
5981
5982 // level of pet summoned using engineering item based at engineering skill level
5983 if (m_CastItem && caster->IsPlayer())
5984 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5985 {
5986 // xinef: few special cases
5987 if (proto->RequiredSkill == SKILL_ENGINEERING)
5988 {
5989 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5990 summonLevel = skill202 / 5;
5991 }
5992
5993 switch (m_spellInfo->Id)
5994 {
5995 // Dragon's Call
5996 case 13049:
5997 summonLevel = 55;
5998 break;
5999
6000 // Cleansed Timberling Heart: Summon Timberling
6001 case 5666:
6002 summonLevel = 7;
6003 break;
6004
6005 // Glowing Cat Figurine: Summon Ghost Saber
6006 case 6084:
6007 // minLevel 19, maxLevel 20
6008 summonLevel = 20;
6009 break;
6010
6011 // Spiked Collar: Summon Felhunter
6012 case 8176:
6013 summonLevel = 30;
6014 break;
6015
6016 // Dog Whistle: Summon Tracking Hound
6017 case 9515:
6018 summonLevel = 30;
6019 break;
6020
6021 // Barov Peasant Caller: Death by Peasant
6022 case 18307:
6023 case 18308:
6024 summonLevel = 60;
6025 break;
6026
6027 // Thornling Seed: Plant Thornling
6028 case 22792:
6029 summonLevel = 60;
6030 break;
6031
6032 // Cannonball Runner: Summon Crimson Cannon
6033 case 6251:
6034 summonLevel = 61;
6035 break;
6036 }
6037 }
6038
6039 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6040
6041 float radius = 5.0f;
6042 int32 duration = m_spellInfo->GetDuration();
6043
6044 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6045 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6046
6047 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6048 Map* map = caster->GetMap();
6049 TempSummon* summon = nullptr;
6050
6051 uint32 currMinionsCount = m_caster->m_Controlled.size();
6052 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6053
6054 for (uint32 count = 0; count < numGuardians; ++count)
6055 {
6056 Position pos;
6057
6058 // xinef: do not use precalculated position for effect summon pet in this function
6059 // it means it was cast by NPC and should have its position overridden unless the
6060 // target position is specified in the DB AND the effect has no or zero radius
6061 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6062 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6063 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6064 {
6065 pos = *destTarget;
6066 }
6067 else
6068 {
6069 // randomize position
6070 pos = m_caster->GetRandomPoint(*destTarget, radius);
6071 }
6072
6073 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6074 if (!summon)
6075 return;
6076
6077 // xinef: set calculated level
6078 summon->SetLevel(summonLevel);
6079
6080 // if summonLevel changed, set stats for calculated level
6081 if (summonLevel != caster->GetLevel())
6082 {
6083 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6084 }
6085
6086 // xinef: if we have more than one guardian, change follow angle
6087 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6088 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6089 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6090 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6091
6092 // xinef: move this here, some auras are added in initstatsforlevel!
6093 if (!summon->IsInCombat() && !summon->IsTrigger())
6094 {
6095 // summon->AI()->EnterEvadeMode();
6096 summon->GetMotionMaster()->Clear(false);
6098 }
6099
6100 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6101 summon->SetFaction(caster->GetFaction());
6102
6104 }
6105}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3163
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:190
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition WorldConfig.h:239
bool IsTrigger() const
Definition Creature.h:80
Definition TemporarySummon.h:87
Unit * GetOwner() const
Definition TemporarySummon.cpp:390
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition Unit.cpp:15704
virtual float GetFollowAngle() const
Definition Unit.h:1875

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5329{
5331 {
5333
5334 // wands don't have ammo
5335 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5336 return;
5337
5338 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5339 {
5340 if (pItem->GetMaxStackCount() == 1)
5341 {
5342 // decrease durability for non-stackable throw weapon
5344 }
5345 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5346 {
5347 // decrease items amount for stackable throw weapon
5348 uint32 count = 1;
5349 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5350 }
5351 }
5352 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5354 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5355 }
5356}
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:679
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition SharedDefines.h:620
@ CONFIG_ENABLE_INFINITEAMMO
Definition WorldConfig.h:146
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4730

References CONFIG_ENABLE_INFINITEAMMO, Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_spellInfo, PLAYER_AMMO_ID, RANGED_ATTACK, SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES, ItemTemplate::SubClass, sWorld, and Object::ToPlayer().

Referenced by handle_immediate(), spell_hun_explosive_shot::HandleFinish(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5202{
5203 if (!m_CastItem || !m_caster->IsPlayer())
5204 return;
5205
5206 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5208 return;
5209
5210 ItemTemplate const* proto = m_CastItem->GetTemplate();
5211
5212 if (!proto)
5213 {
5214 // This code is to avoid a crash
5215 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5216 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5217 return;
5218 }
5219
5220 bool expendable = false;
5221 bool withoutCharges = false;
5222
5223 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5224 {
5225 if (proto->Spells[i].SpellId)
5226 {
5227 // item has limited charges
5228 if (proto->Spells[i].SpellCharges)
5229 {
5230 if (proto->Spells[i].SpellCharges < 0)
5231 expendable = true;
5232
5233 int32 charges = m_CastItem->GetSpellCharges(i);
5234
5235 // item has charges left
5236 if (charges)
5237 {
5238 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5239 if (proto->Stackable == 1)
5240 m_CastItem->SetSpellCharges(i, charges);
5242 }
5243
5244 // all charges used
5245 withoutCharges = (charges == 0);
5246 }
5247 }
5248 }
5249
5250 if (expendable && withoutCharges)
5251 {
5252 uint32 count = 1;
5253 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5254
5255 // prevent crash at access to deleted m_targets.GetItemTarget
5257 m_targets.SetItemTarget(nullptr);
5258
5259 m_CastItem = nullptr;
5261 }
5262}
void SetSpellCharges(uint8 index, int32 value)
Definition Item.h:318
int32 Stackable
Definition ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5265{
5267 return;
5268
5269 //Don't take power if the spell is cast while .cheat power is enabled.
5270 if (m_caster->IsPlayer())
5272 return;
5273
5275 bool hit = true;
5276 if (m_caster->IsPlayer())
5277 {
5279 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5280 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5281 if (ihit->targetGUID == targetGUID)
5282 {
5283 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5284 {
5285 hit = false;
5286 //lower spell cost on fail (by talent aura)
5287 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5288 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5289 }
5290 break;
5291 }
5292 }
5293
5294 if (PowerType == POWER_RUNE)
5295 {
5296 TakeRunePower(hit);
5297 return;
5298 }
5299
5300 if (!m_powerCost)
5301 return;
5302
5303 // health as power used
5304 if (PowerType == POWER_HEALTH)
5305 {
5307 return;
5308 }
5309
5310 if (PowerType >= MAX_POWERS)
5311 {
5312 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5313 return;
5314 }
5315
5316 if (hit)
5318 else
5320
5321 // Set the five second timer
5322 if (PowerType == POWER_MANA && m_powerCost > 0)
5323 {
5325 }
5326}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1540
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:106
void TakeRunePower(bool didHit)
Definition Spell.cpp:5412
int32 ModifyHealth(int32 val)
Definition Unit.cpp:14273
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1136

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5482{
5483 if (!m_caster->IsPlayer())
5484 return;
5485
5486 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5487
5488 // do not take reagents for these item casts
5489 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5490 return;
5491
5492 Player* p_caster = m_caster->ToPlayer();
5493 if (p_caster->CanNoReagentCast(m_spellInfo))
5494 return;
5495
5496 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5497 {
5498 if (m_spellInfo->Reagent[x] <= 0)
5499 continue;
5500
5501 uint32 itemid = m_spellInfo->Reagent[x];
5502 uint32 itemcount = m_spellInfo->ReagentCount[x];
5503
5504 // if CastItem is also spell reagent
5505 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5506 {
5507 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5508 {
5509 // CastItem will be used up and does not count as reagent
5510 int32 charges = m_CastItem->GetSpellCharges(s);
5511 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5512 {
5513 ++itemcount;
5514 break;
5515 }
5516 }
5517
5518 m_CastItem = nullptr;
5520 }
5521
5522 // if GetItemTarget is also spell reagent
5523 if (m_targets.GetItemTargetEntry() == itemid)
5524 m_targets.SetItemTarget(nullptr);
5525
5526 p_caster->DestroyItemCount(itemid, itemcount, true);
5527 }
5528}
uint32 ItemId
Definition ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5413{
5415 return;
5416
5417 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5418 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5419 return;
5420
5421 Player* player = m_caster->ToPlayer();
5422 m_runesState = player->GetRunesState(); // store previous state
5423
5424 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5425
5426 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5427 {
5428 runeCost[i] = runeCostData->RuneCost[i];
5429 if (Player* modOwner = m_caster->GetSpellModOwner())
5430 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5431 }
5432
5433 runeCost[RUNE_DEATH] = 0; // calculated later
5434
5435 for (uint32 i = 0; i < MAX_RUNES; ++i)
5436 {
5437 RuneType rune = player->GetCurrentRune(i);
5438 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5439 {
5440 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5441 player->SetLastUsedRune(rune);
5442 runeCost[rune]--;
5443 }
5444 }
5445
5446 // Xinef: firstly consume death runes of base type
5447 // Xinef: in second loop consume all available
5448 for (uint8 loop = 0; loop < 2; ++loop)
5449 {
5450 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5451 if (runeCost[RUNE_DEATH] > 0)
5452 {
5453 for (uint8 i = 0; i < MAX_RUNES; ++i)
5454 {
5455 RuneType rune = player->GetCurrentRune(i);
5456 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5457 {
5458 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5459 player->SetLastUsedRune(rune);
5460 runeCost[rune]--;
5461 if (!loop)
5462 runeCost[player->GetBaseRune(i)]--;
5463
5464 // keep Death Rune type if missed
5465 if (didHit)
5466 player->RestoreBaseRune(i);
5467
5468 if (runeCost[RUNE_DEATH] == 0)
5469 break;
5470 }
5471 }
5472 }
5473 }
5474
5475 // you can gain some runic power when use runes
5476 if (didHit)
5477 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5478 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5479}
@ RUNE_UNHOLY
Definition Player.h:398
@ RUNE_BLOOD
Definition Player.h:397
@ RUNE_MISS_COOLDOWN
Definition Player.h:392
@ RATE_POWER_RUNICPOWER_INCOME
Definition WorldConfig.h:394
void SetLastUsedRune(RuneType type)
Definition Player.h:2546
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13390
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13419
bool NoRunicPowerGain() const
Definition DBCStructure.h:1811
uint32 runePowerGain
Definition DBCStructure.h:1808

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8844{
8846 if (!gcd)
8847 {
8848 // Xinef: fix for charmed pet spells with no cooldown info
8850 gcd = MIN_GCD;
8851 else
8852 return;
8853 }
8854
8855 if (m_caster->IsPlayer())
8857 return;
8858
8859 // Global cooldown can't leave range 1..1.5 secs
8860 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8861 // but as tests show are not affected by any spell mods.
8863 {
8864 // gcd modifier auras are applied only to own spells and only players have such mods
8865 if (m_caster->IsPlayer())
8867
8868 // Apply haste rating
8871 {
8872 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8873 }
8874
8875 if (gcd < MIN_GCD)
8876 gcd = MIN_GCD;
8877 else if (gcd > MAX_GCD)
8878 gcd = MAX_GCD;
8879 }
8880
8881 // Only players or controlled units have global cooldown
8882 if (m_caster->GetCharmInfo())
8884 else if (m_caster->IsPlayer())
8886}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8828
@ MAX_GCD
Definition Spell.cpp:8829
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition CharmInfo.cpp:419

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4341{
4342 // update pointers based at it's GUIDs
4343 if (!UpdatePointers())
4344 {
4345 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4346 cancel();
4347 return;
4348 }
4349
4351 {
4352 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4353 cancel();
4354 return;
4355 }
4356
4357 // check if the player caster has moved before the spell finished
4358 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4359 if ((m_caster->IsPlayer() && m_timer != 0) &&
4362 {
4363 // don't cancel for melee, autorepeat, triggered and instant spells
4365 cancel(true);
4366 }
4367
4368 switch (m_spellState)
4369 {
4371 {
4372 if (m_timer > 0)
4373 {
4374 if (difftime >= (uint32)m_timer)
4375 m_timer = 0;
4376 else
4377 m_timer -= difftime;
4378 }
4379
4380 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4381 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4382 cast(!m_casttime);
4383 break;
4384 }
4386 {
4387 if (m_timer)
4388 {
4389 if (m_timer > 0)
4390 {
4391 if (difftime >= (uint32)m_timer)
4392 m_timer = 0;
4393 else
4394 m_timer -= difftime;
4395 }
4396 }
4397
4398 if (m_timer == 0)
4399 {
4401
4402 finish();
4403
4404 // We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts
4405 if (Creature* creatureCaster = m_caster->ToCreature())
4406 if (creatureCaster->IsAIEnabled)
4407 creatureCaster->AI()->OnSpellCastFinished(m_spellInfo, SPELL_FINISHED_CHANNELING_COMPLETE);
4408 }
4409 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4410 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4411 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4412 // Xinef: so the aura can be removed in different updates for all units
4413 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4414 {
4415 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4417 finish();
4418 }
4419 break;
4420 }
4421 default:
4422 break;
4423 }
4424}
@ SPELL_FINISHED_CHANNELING_COMPLETE
Definition Spell.h:100
bool UpdateChanneledTargetList()
Definition Spell.cpp:3315

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_FINISHED_CHANNELING_COMPLETE, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, Object::ToCreature(), UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3316{
3317 // Not need check return true
3319 return true;
3320
3321 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3322 uint8 channelAuraMask = 0;
3323 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3325 channelAuraMask |= 1 << i;
3326
3327 channelAuraMask &= channelTargetEffectMask;
3328
3329 float range = 0;
3330 if (channelAuraMask)
3331 {
3333 if (range == 0)
3334 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3335 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3336 {
3337 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3338 break;
3339 }
3340
3341 if (Player* modOwner = m_caster->GetSpellModOwner())
3342 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3343
3344 // xinef: add little tolerance level
3345 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3346 }
3347
3348 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3349 {
3350 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3351 {
3352 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3353
3354 if (!unit)
3355 continue;
3356
3357 if (IsValidDeadOrAliveTarget(unit))
3358 {
3359 if (channelAuraMask & ihit->effectMask)
3360 {
3362 {
3363 if (m_caster != unit)
3364 {
3365 if (!m_caster->IsWithinDistInMap(unit, range))
3366 {
3367 ihit->effectMask &= ~aurApp->GetEffectMask();
3368 unit->RemoveAura(aurApp);
3369 continue;
3370 }
3371 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3374 }
3375 }
3376 else // aura is dispelled
3377 continue;
3378 }
3379
3380 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3381 }
3382 }
3383 }
3384
3385 // Xinef: not all effects are covered, remove applications from all targets
3386 if (channelTargetEffectMask != 0)
3387 {
3388 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3389 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3390 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3391 if (IsValidDeadOrAliveTarget(unit))
3393 {
3394 ihit->effectMask &= ~aurApp->GetEffectMask();
3395 unit->RemoveAura(aurApp);
3396 }
3397 }
3398
3399 // is all effects from m_needAliveTargetMask have alive targets
3400 return channelTargetEffectMask == 0;
3401}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:444
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8216
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5688
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:20049
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1347

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7855{
7858 else
7859 {
7862 m_originalCaster = nullptr;
7863 }
7864
7866 {
7868 // cast item not found, somehow the item is no longer where we expected
7869 if (!m_CastItem)
7870 return false;
7871 }
7872 else
7873 m_CastItem = nullptr;
7874
7876
7877 // further actions done only for dest targets
7878 if (!m_targets.HasDst())
7879 return true;
7880
7881 // cache last transport
7882 WorldObject* transport = nullptr;
7883
7884 // update effect destinations (in case of moved transport dest target)
7885 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7886 {
7887 SpellDestination& dest = m_destTargets[effIndex];
7888 if (!dest._transportGUID)
7889 continue;
7890
7891 if (!transport || transport->GetGUID() != dest._transportGUID)
7893
7894 if (transport)
7895 {
7896 dest._position.Relocate(transport);
7898 }
7899 }
7900
7901 return true;
7902}
void Update(Unit *caster)
Definition Spell.cpp:478
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition Position.cpp:66
Position _transportOffset
Definition Spell.h:115
ObjectGuid _transportGUID
Definition Spell.h:114

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4878{
4879 uint32 ammoInventoryType = 0;
4880 uint32 ammoDisplayID = 0;
4881
4882 if (m_caster->IsPlayer())
4883 {
4885 if (pItem)
4886 {
4887 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4888 if (ammoInventoryType == INVTYPE_THROWN)
4889 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4890 else
4891 {
4893 if (ammoID)
4894 {
4895 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4896 if (pProto)
4897 {
4898 ammoDisplayID = pProto->DisplayInfoID;
4899 ammoInventoryType = pProto->InventoryType;
4900 }
4901 }
4902 else if (m_caster->HasAura(46699)) // Requires No Ammo
4903 {
4904 ammoDisplayID = 5996; // normal arrow
4905 ammoInventoryType = INVTYPE_AMMO;
4906 }
4907 }
4908 }
4909 }
4910 else
4911 {
4912 uint32 nonRangedAmmoDisplayID = 0;
4913 uint32 nonRangedAmmoInventoryType = 0;
4914 for (uint8 i = 0; i < 3; ++i)
4915 {
4917 {
4918 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4919 {
4920 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4921 {
4922 switch (itemEntry->SubclassID)
4923 {
4925 ammoDisplayID = itemEntry->DisplayInfoID;
4926 ammoInventoryType = itemEntry->InventoryType;
4927 break;
4930 ammoDisplayID = 5996; // is this need fixing?
4931 ammoInventoryType = INVTYPE_AMMO;
4932 break;
4934 ammoDisplayID = 5998; // is this need fixing?
4935 ammoInventoryType = INVTYPE_AMMO;
4936 break;
4937 default:
4938 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4939 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4940 break;
4941 }
4942
4943 if (ammoDisplayID)
4944 break;
4945 }
4946 }
4947 }
4948 }
4949
4950 if (!ammoDisplayID && !ammoInventoryType)
4951 {
4952 ammoDisplayID = nonRangedAmmoDisplayID;
4953 ammoInventoryType = nonRangedAmmoInventoryType;
4954 }
4955 }
4956
4957 *data << uint32(ammoDisplayID);
4958 *data << uint32(ammoInventoryType);
4959}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition UpdateFields.h:116
Definition DBCStructure.h:1143
uint32 DisplayInfoID
Definition ItemTemplate.h:625

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4514{
4515 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4516 data << uint32(spellInfo->Id);
4517 data << uint8(result); // problem
4518 switch (result)
4519 {
4521 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4522 break;
4523 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4524 // hardcode areas limitation case
4525 switch (spellInfo->Id)
4526 {
4527 case 41617: // Cenarion Mana Salve
4528 case 41619: // Cenarion Healing Salve
4529 data << uint32(3905);
4530 break;
4531 case 41618: // Bottled Nethergon Energy
4532 case 41620: // Bottled Nethergon Vapor
4533 data << uint32(3842);
4534 break;
4535 case 45373: // Bloodberry Elixir
4536 data << uint32(4075);
4537 break;
4538 default: // default case (don't must be)
4539 data << uint32(0);
4540 break;
4541 }
4542 break;
4544 if (spellInfo->Totem[0])
4545 data << uint32(spellInfo->Totem[0]);
4546 if (spellInfo->Totem[1])
4547 data << uint32(spellInfo->Totem[1]);
4548 break;
4550 if (spellInfo->TotemCategory[0])
4551 data << uint32(spellInfo->TotemCategory[0]);
4552 if (spellInfo->TotemCategory[1])
4553 data << uint32(spellInfo->TotemCategory[1]);
4554 break;
4558 data << uint32(spellInfo->EquippedItemClass);
4559 data << uint32(spellInfo->EquippedItemSubClassMask);
4560 break;
4562 {
4563 uint32 item = 0;
4564 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4565 if (spellInfo->Effects[eff].ItemType)
4566 item = spellInfo->Effects[eff].ItemType;
4567 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4568 if (proto && proto->ItemLimitCategory)
4569 data << uint32(proto->ItemLimitCategory);
4570 break;
4571 }
4573 data << uint32(customError);
4574 break;
4576 {
4577 uint32 missingItem = 0;
4578 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4579 {
4580 if (spellInfo->Reagent[i] <= 0)
4581 continue;
4582
4583 uint32 itemid = spellInfo->Reagent[i];
4584 uint32 itemcount = spellInfo->ReagentCount[i];
4585
4586 if (!caster->HasItemCount(itemid, itemcount))
4587 {
4588 missingItem = itemid;
4589 break;
4590 }
4591 }
4592
4593 data << uint32(missingItem); // first missing item
4594 break;
4595 }
4597 data << uint32(spellInfo->Mechanic);
4598 break;
4600 data << uint32(spellInfo->EquippedItemSubClassMask);
4601 break;
4603 data << uint32(0); // Item entry
4604 data << uint32(0); // Count
4605 break;
4607 data << uint32(0); // SkillLine.dbc Id
4608 data << uint32(0); // Amount
4609 break;
4611 data << uint32(0); // Skill level
4612 break;
4613 default:
4614 break;
4615 }
4616}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition SharedDefines.h:1014
@ SPELL_FAILED_FISHING_TOO_LOW
Definition SharedDefines.h:1141
@ SPELL_FAILED_MIN_SKILL
Definition SharedDefines.h:1110
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition SharedDefines.h:1107
@ SPELL_FAILED_REQUIRES_AREA
Definition SharedDefines.h:1061

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

4963{
4964 // This function also fill data for channeled spells:
4965 // m_needAliveTargetMask req for stop channelig if one target die
4966 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4967 {
4968 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
4969 // possibly SPELL_MISS_IMMUNE2 for this??
4970 ihit->missCondition = SPELL_MISS_IMMUNE2;
4971 }
4972
4973 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
4974 // sending more than 255 targets crashes the client (since count sent would be wrong)
4975 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
4976 // target conditions but we still need to limit the number of targets sent and keeping
4977 // correct count for both hit and miss).
4978
4979 uint32 hit = 0;
4980 std::size_t hitPos = data->wpos();
4981 *data << (uint8)0; // placeholder
4982 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
4983 {
4984 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
4985 {
4986 *data << ihit->targetGUID;
4987 // Xinef: No channeled spell checked, no anything
4988 //m_channelTargetEffectMask |=ihit->effectMask;
4989 ++hit;
4990 }
4991 }
4992
4993 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
4994 {
4995 *data << ighit->targetGUID; // Always hits
4996 ++hit;
4997 }
4998
4999 uint32 miss = 0;
5000 std::size_t missPos = data->wpos();
5001 *data << (uint8)0; // placeholder
5002 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5003 {
5004 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5005 {
5006 *data << ihit->targetGUID;
5007 *data << uint8(ihit->missCondition);
5008 if (ihit->missCondition == SPELL_MISS_REFLECT)
5009 *data << uint8(ihit->reflectResult);
5010 ++miss;
5011 }
5012 }
5013 // Reset m_needAliveTargetMask for non channeled spell
5014 // Xinef: Why do we reset something that is not set??????
5015 //if (!m_spellInfo->IsChanneled())
5016 // m_channelTargetEffectMask = 0;
5017
5018 data->put<uint8>(hitPos, (uint8)hit);
5019 data->put<uint8>(missPos, (uint8)miss);
5020}
std::size_t wpos() const
Definition ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Symbol Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_reflectionTarget

Unit* Spell::m_reflectionTarget
protected

◆ m_reflectionTargetGuid

ObjectGuid Spell::m_reflectionTargetGuid
protected

◆ m_reflectionTargetPosition

Position Spell::m_reflectionTargetPosition
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakeAmmo(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSkinPlayerCorpse(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and Spell().


The documentation for this class was generated from the following files: